题目:澳大利亚选举。有n个候选人m个公民,每一个公民对每一个候选人有一个期望的优先级,
选举时,先按第一优先级分配选票。得票最少的候选人的投票,将按投票人的优先级,
又一次分给留下的候选人,直到某人获得50%或以上的选票。或者剩下的人得票同样。
求选举结果。
分析:模拟。依照上述规则模拟就可以。过程有点麻烦。
说明:数据给事有点恶心,注意到达50%就能够觉得胜利了。不用超过╮(╯▽╰)╭。
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
using namespace std;
char candidate[21][81];
char buf[1001];
int choice[1001][21];
int vote[21][1001];
int vote_size[21];
int main()
{
int t,n;
while (~scanf("%d",&t))
while (t --) {
scanf("%d",&n);
getchar();
for (int i = 0; i < n; ++ i) {
gets(candidate[i]);
vote_size[i] = 0;
}
//提取每一个公民的投票意向
int number = 0;
while (gets(buf) && buf[0]) {
int value = 0, count = 0;
for (int i = 0; buf[i]; ++ i)
if (buf[i] >= '0' && buf[i] <= '9') {
value *= 10;
value += buf[i]-'0';
}else {
choice[number][count ++] = value-1;
value = 0;
}
choice[number ++][count ++] = value-1;
}
//初始化
for (int i = 0; i < number; ++ i) {
int cand = choice[i][0];
vote[cand][vote_size[cand] ++] = i;
}
while (1) {
int max = 0, min = 1001, max_space, min_space;
for (int i = 0; i < n; ++ i)
if (vote_size[i]) {
if (max < vote_size[i]) {
max = vote_size[i];
max_space = i;
}
if (min > vote_size[i]) {
min = vote_size[i];
min_space = i;
}
}
if (max*2 >= number) break;//等于 50%也能够
if (max == min) break;
for (int k = 0; k < n; ++ k) {
if (vote_size[k] != min) continue;
//取出得票最少的人的选票s
for (int i = 0; i < vote_size[k]; ++ i) {
int per = vote[k][i];
//又一次按意向分配当前公民选票
for (int j = 0; j < n; ++ j) {
int can = choice[per][j];
if (vote_size[can] != min && vote_size[can]) {
vote[can][vote_size[can] ++] = per;
break;
}
}
}
vote_size[k] = 0;
}
}
int max_space = 0;
for (int i = 0; i < n; ++ i)
if (vote_size[max_space] < vote_size[i])
max_space = i;
for (int i = 0; i < n; ++ i)
if (vote_size[max_space] == vote_size[i])
puts(candidate[i]);
if (t) puts("");
}
return 0;
}
一些測试数据:
2
3
John Doe
Jane Smith
Sirhan Sirhan
1 2 3
2 1 3
2 3 1
1 2 3
3 1 2
3
John Doe
Jane Smith
Sirhan Sirhan
1 2 3
2 1 3
2 3 1
1 2 3
1
4
A
B
C
D
2 1 3 4
2 1 3 4
3 1 4 2
4 1 2 3