题目链接: https://codeforces.com/contest/1654/problem/C
参考大佬题解链接附上 https://www.acwing.com/solution/content/102783/
解题思路: 对序列求和,从和开始切分模拟。当切分出的数字在序列中存在时删除序列中的数。不存在时对此数字进行切分。巧妙处如下:
1: 用multiset记录序列,提升删除,查找性能,且multiset没有去重效果。
2: 对模拟切分操作进行分析,经过每一次切分操作后数字会多一个,当切分n-1次时,我们可以得到n个数字,此时若序列数不为0(未删除完),说明无法得到题目要求的序列。
#include<iostream>
#include<queue>
#include<set>
using namespace std;
typedef long long ll;
multiset<ll> m;
int main()
{
int t;
cin >> t;
while (t--)
{
int n;
queue<ll> q;
cin >> n;
ll a, ans = 0;
for (int i = 0; i < n; i++)
{
cin >> a;
ans += a;
m.insert(a);
}//输入数据以multiset记录,并求出总和
q.push(ans);//初始化队列
int count = 0, flag = 1;//以count记录切分次数
while (!q.empty())//此处用m.size()做循环条件也可
{
if (count >= n)//每次切分我们能比上一次多一个蛋糕,当切分n-1次,得到n个蛋糕还不满足m序列时说明无法得到题目序列
{
cout << "NO" << endl;
flag = 0;
break;
}
ans = q.front();
q.pop();
if (m.find(ans) != m.end())
{
m.erase(m.find(ans));//用m.erase(ans)会删除掉所有值为ans的项
continue;
}
q.push(ans / 2);
q.push(ans - ans / 2);
count++;
}
if(flag)
cout << "YES" << endl;
m.clear();
}
return 0;
}