Codeforces Global Round 14

A

sb题
判断一下和是不是x就行了
4mins才写完,手速下降严重啊!!
code:

#include<bits/stdc++.h>
#define N 100005
using namespace std;
int n, m, t, a[N];
int main() {
	scanf("%d", &t);
	while(t --) {
		scanf("%d%d", &n, &m);
		int s = 0;
		for(int i = 1; i <= n; i ++) scanf("%d", &a[i]), s += a[i];
		if(s == m) {
			printf("NO\n");
			continue;
		}	
		s = 0;
		printf("YES\n");
		for(int i = 1; i <= n; i ++) {
			if(s + a[i] == m) swap(a[i], a[n]);
				s += a[i];
				printf("%d ", a[i]);
		} printf("\n");
	}
	
	return 0;
}

B

这题竟然是我卡的最久的题
想了一年
发现可以直接考虑面积是不是完全平方数
降至严重
code:

#include<bits/stdc++.h>
using namespace std;
int check(int n) {
	if(!n) return 0;
	int m = sqrt(n);
	return m * m == n;
}
int n, t;
int main() {
	scanf("%d", &t);
	while(t --) {
		scanf("%d", &n);
		if(n & 1) {
			printf("NO\n");
			continue;
		}
		if(check(n / 2) || (n % 4 == 0 && check(n / 4))) printf("YES\n");
		else printf("NO\n");
	}
	return 0;
}

C

也是道简单题
维护m个数

从1到n考虑,对于每个 i,每次把m个数中最小的那个数加上a[i]
然后判断即可
code:

#include<bits/stdc++.h>
#define N 200005
using namespace std;
priority_queue<pair<int,int>,vector<pair<int,int> >,greater<pair<int,int> > >q;
int a[N], n, m, x, ans[N];
int main() {
	int t;
	scanf("%d", &t);
	while(t --) {
		scanf("%d%d%d", &n, &m, &x);
		for(int i = 1; i <= n; i ++) scanf("%d", &a[i]), ans[i] = 0;
		while(q.size()) q.pop();
		for(int i = 1; i <= m; i ++) q.push(make_pair(a[i], i)), ans[i] = i;//, printf("**  %d %d\n", a[i], i);
		for(int i = m + 1; i <= n; i ++) {
			int s = q.top().first, id = q.top().second; q.pop();
		//	printf("  %d %d\n", s, id);
			ans[i] = id; s += a[i];
			q.push(make_pair(s, id));
		}
		int ha = q.top().first, f = 0;
	//	printf("%d\n", ha);
		while(q.size()) {
			if(q.top().first - ha > x) {
				f = 1;
				break;
			}
			q.pop();
		}
		if(f) {
			printf("NO\n");
			continue;
		} 
		printf("YES\n");
		for(int i = 1; i <= n; i ++) printf("%d ", ans[i]); printf("\n");	
	}
	
	return 0;
}

D

sb贪心
直接看代码吧

code:


#include<bits/stdc++.h>
#define N 400005
using namespace std;
int t, n, n1, n2, ha1[N], ha2[N];
int main() {
	scanf("%d", &t);
	while(t --) {
		scanf("%d%d%d", &n, &n1, &n2);
		for(int i = 1, x; i <= n1; i ++) scanf("%d", &x), ha1[x] ++;
		for(int i = 1, x; i <= n2; i ++) scanf("%d", &x), ha2[x] ++;
		if(n1 > n2) for(int i = 0; i <= n; i ++) swap(ha1[i], ha2[i]), swap(n1, n2);
		for(int i = 1; i <= n; i ++) {
			int x = min(ha1[i], ha2[i]);
			ha1[i] -= x, ha2[i] -= x;
		}
		int ans = 0;
		for(int i = 1; i <= n; i ++) ans += ha1[i];
		int s = n / 2 - n1;
		for(int i = 1; i <= n; i ++) {
			while(s && ha2[i] >= 2) ans ++, s --, ha2[i] -= 2;
		}
		ans += s * 2;
		printf("%d\n", ans);
		for(int i = 0; i <= n; i ++) ha1[i] = ha2[i] = 0;	
	}
	
	return 0;
}

E

一开始设了个四维状态的DP, O ( n 4 ) O(n^4) O(n4)很蠢
到结束都没有想出来怎么优化

看题解后发现自己DP像cxk
最后的序列肯定是连续一段手动开的,一个自动开的,连续一段手动开的……
所以可以按照这个分段来DP
设 f [ i ] [ j ] 表 示 目 前 已 经 有 i 个 开 了 , 最 后 一 个 是 自 动 开 的 , 手 动 开 了 j 个 的 方 案 数 设f[i][j]表示目前已经有i个开了,最后一个是自动开的,手动开了j个的方案数 f[i][j]ij
dp就无脑冲就行了
code:

#include<bits/stdc++.h>
#define N 805
#define ll long long
using namespace std;
int n, mod, c[N][N], mi[N];
ll f[N][N];
int main() {
	scanf("%d%d", &n, &mod);
	for(int i = 0; i <= n; i ++) c[i][0] = c[i][i] = 1;
	for(int i = 1; i <= n; i ++)
		for(int j = 1; j <= i; j ++)
			c[i][j] = (c[i - 1][j] + c[i - 1][j - 1]) % mod;
	mi[0] = 1;
	for(int i = 1; i <= n; i ++) mi[i] = mi[i - 1] * 2 % mod;
	
	f[0][0] = 1;
	for(int i = 0; i <= n; i ++)
		for(int j = 0; j <= i; j ++)
			for(int k = 1; k + i <= n; k ++)
				(f[i + k + 1][j + k] += f[i][j] * mi[k - 1] % mod * c[j + k][k]) %= mod;
	ll ans = 0;
	for(int i = 0; i <= n; i ++) ans = (ans + f[n + 1][i]) % mod;
	printf("%lld", ans);
	return 0;
}

posted @ 2021-05-03 21:44  lahlah  阅读(22)  评论(0编辑  收藏  举报