OpenJudge 6377:生日相同 2.0——题解

来源:互联网 发布:全国乡镇经纬度数据库 编辑:程序博客网 时间:2024/04/30 11:44

勇者有很多盆友。
然而勇者却记不住盆友们的生日。
不过幸好的是,勇者有疼讯可以记住他们的生日,并在当天发送礼物。
不过怪麻烦的是,勇者的疼讯版本比较老,于是生日只能一个一个的加,这让勇者有些不耐烦,因为他所知自己的朋友有很多生日相同的,如果一个一个点的话会很麻烦。
于是他希望路由器帮他解决这个问题。
——————————————————
总时间限制: 1000ms 内存限制: 65536kB

描述
在一个有180人的大班级中,存在两个人生日相同的概率非常大,现给出每个学生的名字,出生月日。试找出所有生日相同的学生。

输入
第一行为整数n,表示有n个学生,n ≤ 180。此后每行包含一个字符串和两个整数,分别表示学生的名字(名字第一个字母大写,其余小写,不含空格,且长度小于20)和出生月(1 ≤ m ≤ 12)日(1 ≤ d ≤ 31)。名字、月、日之间用一个空格分隔

输出
每组生日相同的学生,输出一行,其中前两个数字表示月和日,后面跟着所有在当天出生的学生的名字,数字、名字之间都用一个空格分隔。对所有的输出,要求按日期从前到后的顺序输出。 对生日相同的名字,按名字从短到长按序输出,长度相同的按字典序输出。如没有生日相同的学生,输出”None”

样例输入
6
Avril 3 2
Candy 4 5
Tim 3 2
Sufia 4 5
Lagrange 4 5
Bill 3 2

样例输出
3 2 Tim Bill Avril
4 5 Candy Sufia Lagrange

——————————————————
首先路由器并不知道为什么是2.0……然后也不知道为什么OJ上3.1也就只有这么一道题。
思路还是比较清晰的,路由器用桶的想法(什么想法请参考路由器的排序(五)),将生日相同的放在桶里并且用链表连起来,然后在桶里排序在顺序输出即可啦!
思想很简单吧……稍等路由器将代码传上来。
(肯定不是最简的……)

#include<cstdio>#include<cmath>#include<iostream>#include<cstring>#include<algorithm>using namespace std;char a[200][200];int b[200],c[200];int d[13][32][200];int e[13][32]={0};int main(){    int n;    scanf("%d",&n);    for(int i=1;i<=n;i++){        cin>>a[i];        scanf("%d%d",&b[i],&c[i]);        e[b[i]][c[i]]++;        d[b[i]][c[i]][e[b[i]][c[i]]]=i;        if(e[b[i]][c[i]]==1)continue;        int l1=d[b[i]][c[i]][e[b[i]][c[i]]-1];        int l2=d[b[i]][c[i]][e[b[i]][c[i]]];        int len2=strlen(a[l2]);        int len1=strlen(a[l1]);        if(len1>len2||(len1==len2&&strcmp(a[l1],a[l2])>0)){            int t=d[b[i]][c[i]][e[b[i]][c[i]]-1];            d[b[i]][c[i]][e[b[i]][c[i]]-1]=d[b[i]][c[i]][e[b[i]][c[i]]];            d[b[i]][c[i]][e[b[i]][c[i]]]=t;        }    }    int ok=0;    for(int i=1;i<=12;i++){        for(int j=1;j<=31;j++){            if(e[i][j]>=2){                printf("%d %d ",i,j);                for(int k=1;k<=e[i][j];k++){                    for(int l=k+1;l<=e[i][j];l++){                        int l1=d[i][j][k];                        int l2=d[i][j][l];                        int len2=strlen(a[l2]);                        int len1=strlen(a[l1]);                        if(len1>len2||(len1==len2&&strcmp(a[l1],a[l2])>0)){                            int t=d[i][j][k];                            d[i][j][k]=d[i][j][l];                            d[i][j][l]=t;                        }                    }                }                for(int k=1;k<=e[i][j];k++){                    cout<<a[d[i][j][k]]<<' ';                }                printf("\n");                ok=1;            }        }    }    if(ok==0)printf("None");    return 0;}

所以对于勇者这种神奇的要求,路由器决定直接给勇者一巴掌。