题解 [CF1654C] Alice and the Cake

传送门

因为在我还没有完全想到做法时 B 哥把做法喊出来了所以还是写一下

发现最初的蛋糕大小是已知的
发现第一步的切法是固定的
发现若切出了一块给定序列中有的蛋糕,可以直接从原序列中删掉这块蛋糕
发现若没有,只能按固定策略递归切下去
若切出了一个大小为 0 的蛋糕则无解
那么 dfs 树高为 log,最多有 \(n+1\) 个叶子,故复杂度 \(O(n\log n)\)

点击查看代码
#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define N 200010
#define ll long long
#define int long long

char buf[1<<21], *p1=buf, *p2=buf;
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf, 1, 1<<21, stdin)), p1==p2?EOF:*p1++)
inline int read() {
	int ans=0, f=1; char c=getchar();
	while (!isdigit(c)) {if (c=='-') f=-f; c=getchar();}
	while (isdigit(c)) {ans=(ans<<3)+(ans<<1)+(c^48); c=getchar();}
	return ans*f;
}

int n;
int a[N], sum;
map<int, int> mp;

bool dfs(int n) {
	int a=n/2, b=n-a;
	if (!a || !b) return 0;
	if (mp[a]) --mp[a];
	else {if (!dfs(a)) return 0;}
	if (mp[b]) --mp[b];
	else {if (!dfs(b)) return 0;}
	return 1;
}

signed main()
{
	int T=read();
	while (T--) {
		n=read();
		mp.clear(); sum=0;
		for (int i=1; i<=n; ++i) {
			sum+=(a[i]=read());
			++mp[a[i]];
		}
		if (n==1) puts("YES");
		else puts(dfs(sum)?"YES":"NO");
	}

	return 0;
}
posted @ 2022-03-20 21:59  Administrator-09  阅读(6)  评论(0编辑  收藏  举报