加载中...

浙江理工大学入队200题——16F

问题 F: 零基础学C/C++176——生日相同问题

题目描述

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

输入

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

输出

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

样例输入

点击查看代码
6
Avril 3 2
Candy 4 5
Tim 3 2
Sufia 4 5
Lagrange 4 5
Bill 3 2

样例输出 Copy

点击查看代码
3 2 Tim Bill Avril
4 5 Candy Sufia Lagrange

题解

还是自定义函数cmp,不懂的去前2篇博客看一下,不做过多解释。
相当于我们的主要关键字与次要关键字,对于生日相同学生,按照日期名字长短,名字的字典序来排序
首先判断是否存在生日相同的两个人,若有标记为1,然后往后面查找有几个相同生日的,因为已经sort里,找到就直接输出。

代码(AC)

点击查看代码
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <string>
#include <string.h> 
using namespace std;
struct student
{
	char name[25];
	int month;
	int day;
	string s;
	int num;
	int l;
}stu[200];
bool cmp(student a,student b)
{
	if(a.month>b.month) return 0;
	if(a.month<b.month) return 1;
	if(a.day>b.day) return 0;
	if(a.day<b.day) return 1;
	if(a.l>b.l) return 0;
	if(a.l<b.l) return 1;
	if(a.s>b.s) return 0;
	if(a.s<b.s) return 1;
}
int main()
{
	int n;
	scanf("%d",&n);
	for(int i=0;i<n;i++)
	{ 
		scanf("%s%d%d",stu[i].name,&stu[i].month,&stu[i].day);
		stu[i].l=strlen(stu[i].name);//学生姓名长度 
		for(int j=0;j<stu[i].l;j++)
		{
			stu[i].s+=stu[i].name[j];
		}
	}
	sort(stu,stu+n,cmp);
	for(int i=1;i<n;i++)
	{
		if(stu[i].month==stu[i-1].month&&stu[i].day==stu[i-1].day)
		{
			stu[i].num=1;
			stu[i-1].num=1;
		}else stu[i].num=0;
	}
	int what=0;
	for(int i=0;i<n;i++)
	{
		if(stu[i].num==1)
		{
			what=1;
			int m=stu[i].month;
			int d=stu[i].day;
			printf("%d %d",m,d);
			for(int j=i;;j++)
			{
				if(stu[j].month==m&&stu[j].day==d) 
				{
					printf(" %s",stu[j].name);
					i++;
				}else 
				{
					i--;
					break;
				}
			}
			printf("\n");
		}
	}
	if(!what) printf("None\n");
	return 0;
}
posted @ 2022-10-30 10:57  shany212  阅读(137)  评论(0编辑  收藏  举报