题目
n个色盲聚在一 起,讨论一块布的颜色。尽管都是色盲,却盲得各不相同。每个人都有自己的主张,争论不休。最终,他们决定采取民主投票的方式决定布的颜色,不管布同不同 意。某种颜色用字符串表示(字符串为颜色单词或词组,也就是可能有被空格隔开的两个单词组成的颜色词组),只要字符串不同,程序即判断颜色不同。现在给出 这n个人所选择的颜色,输出最有可能的颜色(也就是获得投票最多的颜色),如果有多个颜色获得了最多的投票,则将它们按字典序分行全部输出。
输入
第一行一个正整数n,表示色盲的人数
接下来n行,每行一句话
数据规模和约定
n< =1000
颜色单词最多20个字符,只包含小写字母或者空格
输出
若干行,获得投票最多的颜色,按字典序输出
样例输入
5
red
blue
black
black
blue
样例输出
black
blue
解题思路
首先依次读入色盲的“判断”,每读入一次,便记录在结构体数组中(如果是新出现的颜色,加入结构体数组;如果是已经出现过的颜色,则该颜色的被投票次数增加一)。最后,按要求排序后输出。
易错点
- 读入数字n时,由于下一行需要用fgets读入可能含有空格的字符串,因此,
scanf("%d\n",&n);
(’\n’不要落下,否则会造成字符串比对不一致的问题); - 由于fgets会读入行末的’\n’,因此对’\n’需要进行删除,但最后一行字符串不含有’\n’,因此不需要此操作,否则会删除有效字母。
代码
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
struct cloth{
char name[22];//颜色
int votes;//被投票的次数
};
int cmp_bs(const void *a, const void *b){
char * c = (char *)a;
struct cloth d = *(struct cloth *)b;
return strcmp(c,d.name);
}
int cmp1(const void *a, const void *b){
struct cloth c = *(struct cloth *)a;
struct cloth d = *(struct cloth *)b;
return strcmp(c.name,d.name);//相同票数按字典序输出,升序
}
int cmp(const void *a, const void *b){
struct cloth c = *(struct cloth *)a;
struct cloth d = *(struct cloth *)b;
if (c.votes!=d.votes)
return d.votes-c.votes;//降序
else
return strcmp(c.name,d.name);//相同票数按字典序输出,升序
}
int main()
{
int i,n,num = 0;
char temp[22];
scanf("%d\n",&n);
struct cloth C[n];
struct cloth *pc;
for (i=0;i<n;i++)
{
fgets(temp,22,stdin);//可能包含空格
if (i!=(n-1))
temp[strlen(temp)-1] = '\0';//去除\n
qsort(C,num,sizeof(C[0]),cmp1);
pc = (struct cloth *)bsearch(temp,C,num,sizeof(C[0]),cmp_bs);
if (pc==NULL)//找不到对应的
{
strcpy(C[num].name,temp);
C[num++].votes = 1;
}
else
{
(*pc).votes++;
}
}
qsort(C,num,sizeof(C[0]),cmp);
for (i=0;i<num;i++)
{
if (C[i].votes!=C[0].votes)
break;
printf("%s\n",C[i].name);
}
return 0;
}