首页 > 代码库 > 百度之星2014复赛 - 1001 - Find Numbers

百度之星2014复赛 - 1001 - Find Numbers

先上题目:

Find Numbers

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 26    Accepted Submission(s): 20
Special Judge


Problem Description
给n个非负整数,满足对于某正整数k,n=2^k-1。从中选出(n+1)/2个数,使得它们的和是(n+1)/2的倍数。
 

 

Input
第一行,T,询问个数。
下面2T行,每两行是一个询问。对于每两行:
第一行,n。
第二行,n个整数,a_0, a_1, ..., a_{n-1}。

数据范围:
1<=T<=20
1<=n<=2^15
0<=a_i<=10^9
 

 

Output
对第i个(1<=i<=T)询问的回答为两行,第一行为编号:
Case #i:
第二行为结果:
如果不能选出这样的(n+1)/2个数,输出-1;
否则输出一行,用一个空格分隔的(n+1)/2个数b_0, b_1, ..., b_{(n+1)/2-1}。满足0<=b_i<n, b_i两两不同,且sum(a_{b_i})是(n+1)/2的倍数。如果有多解,输出任意一个。
 

 

Sample Input
2
3
1 3 5
7
0 1 2 3 4 5 6
 

 

Sample Output
Case #1:
0 2
Case #2:
0 2 4 6
 

 

Source
2014年百度之星程序设计大赛 - 复赛
 
  中文题意不解释,做法读入所有数字以后保存它们以及它们的下标,然后按照数字大小排序(这里没有看百度放出来的题解,不知道是不是一定要排序,反正我觉得排下序应该也没事),然后枚举数字选(n+1)/2个,如果符合条件就打印,否则继续枚举,知道无法枚举就输出-1。
  上面说的方法很暴力,但还是过了,一开始觉得是不是数据太水了,然后想了一下觉得有可能不是,虽然还没有完全想明白,但是我觉得可能与题目中几个信息点有关:①目标状态是(n+1)/2的倍数,同时要知道n=2^k-1,也就是说结果是二的次幂的倍数。②感觉输出-1的情况可能很少,或者甚至不会出现,自己想找一组可以输出-1的数据的时候发现好像挺难找的。
  总的来说这一题还没有完全弄懂,虽然过了→_→,等有题解的时候去看看。
 
上代码:
 
 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <stack>
 5 #include <utility>
 6 #define MAX 32770
 7 #define LL long long
 8 using namespace std;
 9 
10 typedef pair<int,LL> pii;
11 
12 pii s[MAX];
13 int n,e;
14 LL f;
15 stack<int> st;
16 
17 bool dfs(int c){
18     if(!e){
19         if(f%((n+1)/2)==0) return 1;
20         return 0;
21     }
22     for(int i=c;i<n;i++){
23         st.push(s[i].first);
24         f+=s[i].second;
25         e--;
26         if(dfs(i+1)) return 1;
27         st.pop();
28         f-=s[i].second;
29         e++;
30     }
31     return 0;
32 }
33 
34 
35 
36 int main()
37 {
38     int t;
39     //freopen("data.txt","r",stdin);
40     scanf("%d",&t);
41     for(int z=1;z<=t;z++){
42         scanf("%d",&n);
43         e = (n+1)>>1;
44         for(int i=0;i<n;i++){
45             scanf("%I64d",&s[i].second);
46             s[i].first=i;
47         }
48         sort(s,s+n);
49         while(!st.empty()) st.pop();
50         f=0;
51         printf("Case #%d:\n",z);
52         if(!dfs(0)) printf("-1");
53         else for(int i=0;!st.empty();i++){
54             if(i) putchar( );
55             printf("%d",st.top());
56             st.pop();
57         }
58         putchar(\n);
59     }
60     return 0;
61 }
1001