题目 1558: 色盲的民主

这篇博客介绍了一种算法,用于处理色盲人群对布料颜色投票的情况。通过读取每个人的选择,记录并计票,最终按照字典序输出得票最多的颜色。在实现过程中,注意了对fgets的使用以处理可能的空格,并在读取后删除行末的换行符。代码中使用了结构体数组、排序和二分查找等技术来完成任务。
摘要由CSDN通过智能技术生成

题目

n个色盲聚在一 起,讨论一块布的颜色。尽管都是色盲,却盲得各不相同。每个人都有自己的主张,争论不休。最终,他们决定采取民主投票的方式决定布的颜色,不管布同不同 意。某种颜色用字符串表示(字符串为颜色单词或词组,也就是可能有被空格隔开的两个单词组成的颜色词组),只要字符串不同,程序即判断颜色不同。现在给出 这n个人所选择的颜色,输出最有可能的颜色(也就是获得投票最多的颜色),如果有多个颜色获得了最多的投票,则将它们按字典序分行全部输出。

输入
第一行一个正整数n,表示色盲的人数
接下来n行,每行一句话

数据规模和约定
n< =1000
颜色单词最多20个字符,只包含小写字母或者空格

输出
若干行,获得投票最多的颜色,按字典序输出

样例输入

5 
red 
blue 
black 
black 
blue 

样例输出

black
blue

解题思路

首先依次读入色盲的“判断”,每读入一次,便记录在结构体数组中(如果是新出现的颜色,加入结构体数组;如果是已经出现过的颜色,则该颜色的被投票次数增加一)。最后,按要求排序后输出。

易错点

  1. 读入数字n时,由于下一行需要用fgets读入可能含有空格的字符串,因此,scanf("%d\n",&n);(’\n’不要落下,否则会造成字符串比对不一致的问题);
  2. 由于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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值