NYIST20级计科-acm-新生赛第一场(3月12号)

QWQ;
点我 比赛链接
密码:1213;

C题:查阅资料得知此题为记忆化搜索经典例题,为我未学习算法设暂留问题;
POJ - 1088

A题:POJ - 1321

知识点: dfs;

ACcode

/*
	author:nttttt;
	add oil!
*/

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
#include<stack>
#include<string>
#include<cmath>
#include<vector>
#include<functional>//使用 greater<int>();
using namespace std;
typedef long long ll;
typedef pair<int,int> pll;
const int INF = 0x3f3f3f3f;
const int N = 10;

int n,k;
char mp[N][N];
int cnt,row,res;
bool col[N];

void dfs(int cur)
{
	if(cnt == k)
	{
		res++;
		return ;
	}
	if(cur > n)
		return ;
		
	for(int j = 1; j <= n; j++)
	{
		if(mp[cur][j] == '#' && !col[j])
		{
			col[j] = true;
			cnt++;
			dfs(cur+1);
			col[j] = false;
			cnt--;
		}
	}
	dfs(cur+1);	
}
int main()
{
	while(cin >> n >> k)
	{
		res = 0;
		cnt = 0;
		if(n==-1 && k == -1)
			break;
		memset(mp,0,sizeof(mp));
		memset(col,false,sizeof(col));
		for(int i = 1; i <= n; i++)
		{
			scanf("%s",mp[i] + 1);	
		}
		
		dfs(0);
			
		cout << res << endl;	
	}
	
	
	return 0;
}

反思: 类似于n皇后问题的一道深搜题,接下来重点算法dfs and bfs;

B题.POJ - 1988
知识点:经典并查集:
ACcode:

/*
	author:nttttt;
	add oil!
*/

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
#include<stack>
#include<string>
#include<cmath>
#include<vector>
#include<functional>//使用 greater<int>();
using namespace std;
typedef long long ll;
typedef pair<int,int> pll;
const int INF = 0x3f3f3f3f;
const int N = 5e4;
int arry[N];
int pre[N];
int rank[N];
int va[N];
int siz[N];
void init()
{
	for(int i = 1; i <= 3e4; i++)
	{
		pre[i] = i;
		siz[i] = 1;
	}
}
int find(int x)
{
	if(x != pre[x])
	{
		int fa = pre[x];
		pre[x] = find(pre[x]);
		va[x] += va[fa];
	}
	return pre[x];
}

void merge(int x, int y)
{
	int rx = find(x);
	int ry = find(y);
	
	if(rx != ry)
	{
		va[ry] = siz[rx];
		siz[rx] += siz[ry];
		pre[ry] = rx;
	}
}


int main()
{
	init();
	
	int t;
	cin >> t;
	char c;
	int n,m;
	int k;
	while(t--)
	{
		cin >> c;
		if(c == 'M')
		{
			cin >> n >> m;
			merge(n,m);
		}
		else
		{
			cin >> k;
			int ft = find(k);
			cout << abs(siz[ft] - va[k] - 1) << endl;
		}
	}
	return 0;
}

反思: 比赛前做过一次,啊啊啊啊,经典不会学习的毛病,要认真对待每一道题!!!
简单带权并查集,思维。

D题:Gym - 101498H

知识:思维;

ACcode:

#include <map>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <cstdio>
#include <string>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
 
using namespace std;
const int MX = 1e6 + 5;
const int mod = 1e9 + 7;
const int INF = 2e9 + 5;
 
char s[MX];
 
int main(){
    int t;
    scanf("%d", &t);
    while(t--){
        int n, ss;
        scanf("%d%d", &n, &ss);
        for(int i = 1; i <= n; i++){
            s[i] = '9';
        }
        int sum = n * 9;
        int mid = (1+n)/2;
        if(sum < ss || (n % 2 == 0 && (ss & 1)) || (n & 1 && n != 1 && ss == 1)){
            printf("-1\n");
            continue;
        }
        if(n & 1){
            while(sum > ss && s[mid] > '0'){
                s[mid]--;
                sum--;
                if(s[mid] == '1' && (ss & 1)) break;
            }
            if(sum == ss){
                for(int i = 1; i <= n; i++){
                    printf("%c", s[i]);
                }
                printf("\n");
                continue;
            }
            else mid--;
            while(sum > ss){
                s[mid]--;
                s[n - mid + 1]--;
                sum -= 2;
                if(s[mid] == '0')   mid--;
            }
        }
        else{
            while(sum > ss){
                s[mid]--;
                s[n - mid + 1]--;
                sum -= 2;
                if(s[mid] == '0')   mid--;
            }
        }
        for(int i = 1; i <= n; i++){
            printf("%c", s[i]);
        }
        printf("\n");
    }
    return 0;
}

反思:没什么好说的,思维题,以后多加练习的题型;
这道题注意 为-1的情况;
1, n为偶s为奇;
2. 9n < s;
3. n为奇,n!= 1,s = 1;

F题:CodeForces - 192A

知识点: 打表+思维;

AC code:

/*
	author:nttttt;
	add oil!
*/

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
#include<stack>
#include<string>
#include<cmath>
#include<vector>
using namespace std;
typedef long long ll;
typedef pair<int,int> pll;
int INF = 6e4;
const int N = 1e6 + 10;
int arry[N];
int pre[N];
int rank[N];
long long va[N];

void init()
{
	for(int i = 1; i <= INF;i++)
	{
		va[i-1] = i*(i+1) / 2;
	}
}
int main()
{
	init();
	
	int n;
	cin >> n;
	long long idx;
	long long tp;
	bool flag;
	for(int i = 0; i < INF;i++)
	{
		flag = true;
		tp = n - va[i];
		if(tp < 0) break;
		
		idx = lower_bound(va,va+INF,tp) - va; //重点; 
		
		if(va[idx] == tp)
		{
			cout << "YES"<<endl;
			flag = false;
			break;
		}
	}
	if(flag) puts("NO"); 
	return 0;
}

知识:
函数 lower_bound(begin,end,mun)//找到大于等于mun的数 返回值 - begin 为 找到的数的下标,未找到返回end;//必须减值
函数 power_bound(begin,end,mun)//找到大于mun的数
使用 greater<>(),可以找到小于/等于 数!;

G题:CodeForces - 1118B

题型:思维;

AC代码:

/*
	author:nttttt;
	add oil!
*/

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
#include<stack>
#include<string>
#include<cmath>
#include<vector>
using namespace std;
typedef long long ll;
typedef pair<int,int> pll;
const int INF = 0x3f3f3f3f;
const int N = 2e5+10;
int va[N];
int a[N];
int odd[N];
int even[N];

int main()
{
	int n;
	cin >> n;
	for(int i = 1; i <= n; i++)
		cin >> a[i];
	odd[0] = even[0] = 0;
	for(int i = 1; i <= n ; i++)
	{
		if(i&1)
		{
			odd[i] = odd[i-1] + a[i];
			even[i] = even[i-1];	
		}
		else
		{
			even[i] = even[i-1] + a[i];
			odd[i] = odd[i-1];		
		}	
	}
	int ans;
	int res;
	int cnt = 0;
	for(int i = 1; i <= n; i++)
	{
		if(i&1)
		{
			ans = odd[i-1] + even[n] - even[i - 1];
			res = even[i-1]+ odd[n] - odd[i];	
		}
		else
		{
			ans = odd[i-1] + even[n] - even[i];
			res = even[i-1]+ odd[n] - odd[i-1];
		}
		if(res == ans)
			cnt++;	
	}
	cout << cnt << endl;	
	return 0;
}

技巧点: 前缀和分奇偶处理:

for(int i = 1; i <= n ; i++)
	{
		if(i&1)
		{
			odd[i] = odd[i-1] + a[i];
			even[i] = even[i-1];	
		}
		else
		{
			even[i] = even[i-1] + a[i];
			odd[i] = odd[i-1];		
		}	
	}

H-HDU - 1789

知识点:并查集的应用:

重点思考,使用并查集压缩路径的特征来解决问题;

AC code:

/*
	author:nttttt;
	add oil!
*/

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
#include<stack>
#include<string>
#include<cmath>
#include<vector>
using namespace std;
typedef long long ll;
typedef pair<int,int> pll;
const int INF = 0x3f3f3f3f;
const int N = 1e3 + 10;
int arry[N];
int pre[N];
int rank[N];
int va[N];


int find(int x)
{
	return x == pre[x] ? x : (pre[x] = find(pre[x]));
}
struct Q
{
	int d;
	int f;
}p[N];

bool cmp(Q a, Q b)
{
	return a.f > b.f;
}

int main()
{
	int t;
	cin >> t;
	while(t--)
	{
		memset(pre,0,sizeof(pre));
		memset(p,0,sizeof(p));
		int n;
		cin >> n;
		int max = -1;
		for(int i = 1; i <= n; i++)
		{
			cin >> p[i].d;
			if(p[i].d > max)
				max = p[i].d;
		}
		for(int i = 1; i<= n; i++)
			cin >> p[i].f;
		int res = 0;
		
		for(int i = 1; i<= max; i++)
		{
			pre[i] = i;
		}
		sort(p+1,p+n+1,cmp);	
		//cout << p[1].f << p[2].f;	
			
		for(int i = 1; i <= n;i++)
		{
			int fa = find(p[i].d);
			if(fa <= 0)
			{
				res += p[i].f;
				continue;
			}
			pre[fa] = fa - 1;
		}
		cout << res << endl;
	}
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值