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

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

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

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值