杭电OJ题 1557 权利指数 解题报告

权利指数

Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 492    Accepted Submission(s): 337



Problem Description
在选举问题中,总共有n个小团体,每个小团体拥有一定数量的选票数。如果其中m个小团体的票数和超过总票数的一半,则此组合为“获胜联盟”。n个团体可形成若干个获胜联盟。一个小团体要成为一个“关键加入者”的条件是:在其所在的获胜联盟中,如果缺少了这个小团体的加入,则此联盟不能成为获胜联盟。一个小团体的权利指数是指:一个小团体在所有获胜联盟中成为“关键加入者”的次数。请你计算每个小团体的权利指数。
 

Input
输入数据的第一行为一个正整数T,表示有T组测试数据。每一组测试数据的第一行为一个正整数n(0
 

Output
对每组测试数据,在同一个行按顺序输出1到n号小团体的权利指数。
 

Sample Input
 
   
2 1 10 7 5 7 4 8 6 7 5
 

Sample Output
 
   
1 16 22 16 24 20 22 16
 
————————————————————————————————————————————————————
先从小到大排序,然后DFS,应为如果没有排序,结果会丢失,原因是当在没有排序的情况下,当条件满足的时候就停止DFS,如果后面有数字满足条件,但可有可无的时候也算一种情况,没有考虑就错了

/****************************
 *Name:权利指数.c
 *Tags:ACM water
 *Note:先从小到大排序,然后DFS,应为如果没有排序,结果会丢失,原因是当在没有排序的情况下,当条件满足的时候就停止DFS,如果后面有数字满足条件,但可有可无的时候也算一种情况,没有考虑就错了
 ****************************/

#include 

void dfs(int, int);
void count();
int man[20][3];
int group[20];
int sum = 0;
int n, g;
int main()
{
      int t, i, s, j;
      scanf("%d", &t);
      while(t--) {
	    scanf("%d", &n);
	    sum = 0;
	    for(i = 0; i < n; i++) {
		  scanf("%d", &man[i][0]);
		  man[i][1] = 0;
		  man[i][2] = i;
		  sum += man[i][0];
	    }
	    if(n == 1) {
		  printf("%d\n", 1);
		  continue;
	    }
	    for(i = 0; i < n-1; i++) {
		  for(j = 0; j < n-1-i; j++) {
			if(man[j][0] > man[j+1][0]) {
			      s = man[j][0];
			      man[j][0] = man[j+1][0];
			      man[j+1][0] = s;
			      s = man[j][2];
			      man[j][2] = man[j+1][2];
			      man[j+1][2] = s;
			}
		  }
	    }
	    sum /= 2;
	    for(i = 0; i < n; i++) {
		  g = 0;
		  s = man[i][0];
		  group[g++] = i;
		  if(s > sum) {
			man[i][1] += 1;
		  } else {
			dfs(i+1, s);
		  }
	    }
	    for(i = 0; i < n-1; i++) {
		  for(j = 0; j < n-1-i; j++) {
			if(man[j][2] > man[j+1][2]) {
			      s = man[j][2];
			      man[j][2] = man[j+1][2];
			      man[j+1][2] = s;
			      s = man[j][1];
			      man[j][1] = man[j+1][1];
			      man[j+1][1] = s;
			}
		  }
	    }
	    printf("%d", man[0][1]);
	    for(i = 1; i < n; i++) {
		  printf(" %d", man[i][1]);
	    }
	    printf("\n");
      }
      return 0;
}

void dfs(int i, int s)
{
      int j;
      for(i = i; i < n; i++) {
	    s += man[i][0];
	    group[g++] = i;
	    if(s > sum) {
		  for(j = 0; j < g; j++) {
			if((s - man[group[j]][0]) <= sum) {
			      man[group[j]][1]++;
			}
		  }
	    } else {
		  dfs(i+1, s);
	    }
	    s -= man[i][0];
	    g--;
      }
}


你可能感兴趣的:(杭电ACM)