14. 评选最佳品牌
题目ID:9915必做题100分
时间限制: 200ms
空间限制: 65535kB
题目描述
n个评委投票,在m个商品中评选一个最佳品牌。评选采用多轮淘汰制,即:每轮投票,淘汰掉得票最少的候选品牌(得票并列最少的品牌一起淘汰)。
如此一轮轮淘汰下去,如果最后只剩下一个品牌当选,即告评选成功。但如果在某轮投票中,当时未被淘汰的所有候选品牌(大于等于两个品牌)都并列得票最少,即告评选失败。如果评选成功就输出当选品牌号。否则输出最后一轮评选时唯一选票数的相反数。
在评选流程中,每个评委的态度都可用一个序列来表示。例如当m=5时,某评委的评选态度序列为:3、5、1、2、4,则表示该评委:优先投3号,当3号被淘汰时投5号,当3和5都被淘汰时投1,当3、5、1都被淘汰时投2,仅剩4号时才投4号品牌的票。选票的序列中可以表示弃权,用0来表示,例如当m=5时,某评委的评选态度序列为:3、5、0,则表示该评委:优先投3号,当3号被淘汰时投5号,其它情况下不投任何品牌的票。请你编一个程序,模拟各轮投票的过程,得到评选结果。
输入格式
第一行:m(0<m<10,表示参加评选的商品数)和n(n<1000, 表示参加投选的评委数),之间用空格隔开;接下来的 n 行:每行都是长度不超 m 的数字字符串,每个字符串表示一个评委的评选态度。
输出格式
一个整数,表示评选结果。
样例
Input 1
3 4
123
213
132
10
Output 1
1
Input 2
3 4
321
213
231
312
Output 2
-2
样例解释
对于样例 1:
第一轮,1 号产品 3 票,2 号产品 1 票,3 号产品 0 票,所以淘汰 3 号;
第二轮,1 号产品 3 票,2 号产品 1 票,3 号已被淘汰不计入,所以淘汰 2 号;
最终,票选结果为 1 号产品。
数据范围
m和n均为整数,m的范围是(0,10),n的范围是(0,1000)。
提示
本题对理解题意很关键,每位评委给出的投票序列是按照优先级列出的,比如某个评委的投票序列为 12345,当进行 3 轮的时候,只要 1 号产品没被淘汰,那么这个评委在第 1、2、3 轮票选的都是 1 号产品,如果 1 号产品被淘汰了,那么接下来这个评委票选的就要是 2 号产品了。另外,一轮淘汰时,可以淘汰多个产品,也就是 5 个产品若是出现票数 5、3、7、8、3 的情况,那么 2 号和 5 号产品都会被淘汰。
最终要在 mm 个产品中票选出一个产品,进行的评选轮次却不一定是 m−1m−1 轮,因为一轮可能会淘汰多个产品,因此我们需要一个计数变量来统计已经淘汰了多少个产品。另外,为了方便记录淘汰了哪些产品,以及每位评委该轮将票选哪个产品,我们可以定义一个结构体代表一个评委的票选情况。这里给一个例子:
int n, m, k, p[10]; // 评委个数、产品个数、已淘汰个数,产品淘汰标记数组
struct Votes {
int cur = 0; char v[10]{}; // v 是票选序列,cur 表示票选序列的票选产品下标
// 当前评委认可的产品,当返回值为 0 的时候表示弃权
int favor() {
while (p[v[cur] - '0'] == 1 && cur + 1 < m) ++cur;
return v[cur] - '0';
}
} a[1005];
当剩余未被淘汰的产品不少于 2 个(m−k>1m−k>1),而且又没有出现评选失败的情况下,我们就要进行一轮评选,反复循环。在循环体里,我们可以开一个计数数组 ww 来统计剩余产品的票选结果,并找出投票最多的和最少的。如果投票最多的和最少的选票数目一样,说明剩余产品得票完全相同,也意味着评选失败,只需输出相应结果并结束程序。否则,我们就遍历所有产品,将该轮淘汰的产品打上标记,并累计此轮淘汰了几个。直至最终未被淘汰的只剩一个,输出其编号即可。