题干:
On the table there are n weights. On the body of the i-th weight carved a positive integer kiki , indicating that its weight is 12ki12ki gram. Is it possible to divide the n weights into two groups and make sure that the sum of the weights in each group is greater or equal to 1212 gram? That’s on your call. And please tell us how if possible.
Input
In the first line of the input there is a positive integer TT (1 ≤ TT ≤ 2000), indicating there are TT testcases.
In the first line of each of the TT testcases, there is a positive integer nn (1 ≤ nn ≤ 105105, ∑n ≤ 7 × 105105), indicating there are nn weights on the table.
In the next line, there are nn integers kiki (1 ≤ ki ≤ 109109), indicating the number carved on each weight.
Output
For each testcase, first print Case ii: ANSWER in one line, ii indicating the case number starting from 11 and ANSWER should be either YES or NO, indicating whether or not it is possible to divide the weights. Pay attention to the space between : and ANSWER.
If it’s possible, you should continue to output the dividing solution by print a 0/1 string of length nn in the next line. The ii-th character in the string indicating whether you choose to put the i-th weight in group 0 or group 1.
Sample Input
3
3
2 2 2
3
2 2 1
2
1 1
Sample Output
Case 1: NO
Case 2: YES
001
Case 3: YES
10
题目大意:
给你 n 个数,如果这个数是k,代表的权值为 。让你把 n 个数分成两堆,其中每一堆权值和大于等于 1/2。n<1e5, ai<1e9。
要求输出是否可以凑出来,如果可以,要求输出每个数属于哪一个集合,让你输出0或者1。
解题报告:
已经变成了套路题。容易发现两个k可以合成为k-1,所以题意转换一下:按照上述合并规则,答案有解当且仅当可以合成两个1。
所以直接贪心,从小到大搞就好了,拿个set在线维护出现的元素。从大到小搞应该也是可以的,但是不能不排序就乱搞。
之前出现过的类似题有:【CodeForces - 988C 】Equal Sums
AC代码:
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<stack>
#include<map>
#include<vector>
#include<set>
#include<string>
#include<cmath>
#include<cstring>
#define FF first
#define SS second
#define ll long long
#define pb push_back
#define pm make_pair
using namespace std;
typedef pair<int,int> PII;
const int MAX = 2e5 + 5;
set<int> ss;
struct Node {int a,id;bool operator<(const Node & b) const {return a < b.a;}
} R[MAX];
int tmp,n,tar,ans[MAX];
int main()
{int T,iCase=0;cin>>T;while(T--) {scanf("%d",&n);ss.clear();tar=-1;for(int i = 1; i<=n; i++) scanf("%d",&R[i].a),R[i].id = i,ans[i]=0;printf("Case %d: ",++iCase); sort(R+1,R+n+1);for(int i = 1; i<=n; i++) {tmp=R[i].a;ans[R[i].id] = 1;while(ss.count(tmp) && tmp >= 2) ss.erase(tmp),tmp--;ss.insert(tmp);if(tmp == 1) {tar = i+1;break;}}if(tar==-1) {puts("NO");continue;}ss.clear();for(int i = tar; i<=n; i++) {tmp=R[i].a;while(ss.count(tmp) && tmp >= 2) ss.erase(tmp),tmp--; ss.insert(tmp);if(tmp == 1) {tar = 1000000000;break;}}if(tar != 1000000000) {puts("NO");continue;} puts("YES");for(int i = 1; i<=n; i++) printf("%d",ans[i]);puts("");}return 0 ;
}
总结:
两个地方:首先cmp函数又忘写return了。第二刚开始写成了tmp>=1了,其实应该是tmp>=2