先上题目:
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
中文题意不解释,做法读入所有数字以后保存它们以及它们的下标,然后按照数字大小排序(这里没有看百度放出来的题解,不知道是不是一定要排序,反正我觉得排下序应该也没事),然后枚举数字选(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
百度之星2014复赛 - 1001 - Find Numbers