ZOJ1845 Australian Voting

ZOJ1845 Australian Voting


题目链接: http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=845
Australian ballots require that the voter rank the candidates in order of choice. Initially only the first choices are counted and if one candidate receives more than 50% of the vote, that candidate is elected. If no candidate receives more than 50%, all candidates tied for the lowest number of votes are eliminated. Ballots ranking these candidates first are recounted in favour of their highest ranked candidate who has not been eliminated. This process continues [that is, the lowest candidate is eliminated and each ballot is counted in favour of its ranked non-eliminated candidate] until one candidate receives more than 50% of the vote or until all candidates are tied.

Input

The first line of input is an integer n <= 20 indicating the number of candidates. The next n lines consist of the names of the candidates in order. Names may be up to 80 characters in length and may contain any printable characters. The next line contains an integer m <= 1000, and m lines follow; each contains the contents of a ballot. That is, each contains the numbers from 1 to n in some order. The first number indicates the candidate of first choice; the second number indicates candidate of second choice, and so on.

Process to the end of file.

Output

The Output consists of either a single line containing the name of the winner or several lines containing the names of the candidates who tied.

Sample Input

3
John Doe
Jane Smith
Sirhan Sirhan
5
1 2 3
2 1 3
2 3 1
1 2 3
3 1 2

Sample Output

John Doe
【题意】
给出n个候选人的名字,以及m个选民的投票,投票以类似于高考志愿的形式给出,例如1 2 3,表示第一志愿是候选人1,第二志愿是候选人2,第三志愿是候选人3。最开始时,都以第一志愿统计结果,如果有候选人的票数超过总票数的一半,则该候选人当选,否则所有票数最少的候选人都将被淘汰,然后那些投票给这个候选人的选民,就要根据自己的下一志愿投票给另一个候选人(投票给的那个候选人必须没有被淘汰),直到有候选人的票数超过总票数的一半或者剩下未被淘汰的候选人的票数均相等,打印一行或者多行,表示最后的结果
【思路】
判断当前所有未淘汰的候选人的票数是否相等以及是否有候选人的票数超过总票数的一半,没有则将票数最少的候选人的票根据志愿给其他候选人,用一个数组来储存每个选民当前的志愿,但是WA了…
【代码】

#include<iostream>//ZOJ1845
#include<map>
#include<string>
#include<cstring>
#include<cstdio>
using namespace std;
int sum[30];//保存每个候选人的票数
int elim[30];//是否被淘汰1
int n,m;
bool judge() {
    
    //判断所有未被淘汰的候选人的票数是否相等
	int flag=0,k;
	for(int i=1; i<=n; i++) {
    
    
		if(elim[i]==0) {
    
    
			if(flag==0) {
    
    
				k=sum[i];
				flag=1;
				continue;
			} else {
    
    
				if(sum[i]!=k) return false;
			}
		}
	}
	return true;
}
int main() {
    
    
	freopen("1.txt","r",stdin);
	string s;
	char name[30][1000];
	while(~scanf("%d",&n)) {
    
    
		getline(cin,s);
		for(int i=1; i<=n; i++) {
    
    
			scanf("%[^\n]",&name[i]);
			getchar();
		}
		int vote[2000][30];
		scanf("%d",&m);
		for(int i=1; i<=m; i++) {
    
    
			for(int j=1; j<=n; j++) {
    
    
				scanf("%d",&vote[i][j]);
			}
		}
		memset(elim,0,sizeof(elim));
		memset(sum,0,sizeof(sum));
		for(int i=1; i<=m; i++) {
    
    
			sum[vote[i][1]]++;
		}
		if(judge()) {
    
    
			for(int i=1; i<=n; i++) {
    
    
				printf("%s\n",name[i]);
			}
			continue;
		}
		int flag=0;
		int index[2000];//每个选民当前志愿的位置
		for(int i=1; i<=1000; i++) index[i]=1;
		while(true) {
    
    
			int minn=n;
			for(int i=1; i<=n; i++) {
    
    
				if(sum[i]<minn&&elim[i]==0) {
    
    //找出未被淘汰的候选人中的最小票数
					minn=sum[i];
				}
				if(sum[i]>m/2) {
    
    //如果有候选人的票数已经超过了一半
					flag=1;
					printf("%s\n",name[i]);
					break;
				}
			}
			if(flag==1) {
    
    
				break;
			}
			for(int i=1; i<=n; i++) {
    
    
				if(sum[i]==minn&&elim[i]==0) {
    
    //如果该候选人的票数等于最小票数,并且还未被淘汰
					elim[i]=1;
					for(int j=1; j<=m; j++) {
    
    
						if(vote[j][index[j]]==i) {
    
    
							//如果该候选人已经被淘汰或者即将被淘汰,则继续判断下一个
							while(elim[vote[j][index[j]]]!=0||sum[vote[j][index[j]]]==minn) index[j]++;
							sum[vote[j][index[j]]]++;
						}
					}
				}
			}
			if(judge()) break;
		}
		if(flag==0) {
    
    
			for(int i=1; i<=n; i++) {
    
    
				if(elim[i]==0){
    
    
					printf("%s\n",name[i]);
				}
			}
		}
	}
	return 0;
}

也不知道是题意理解错了,还是细节问题,留着给以后写吧,网上搜了下,也都没有搜到,难道已经简单到没人想写这题了?

猜你喜欢

转载自blog.csdn.net/lmmmmmmmmmmmmmmm/article/details/89301011