首先题目也很明确的要求了按照日期从前到后,若日期相同,则比的是名字从短到长顺序输出,长度相同的按字典序输出。如果没有生日相同的学生,输出None。
所以这题的一大难点也就是排序,如果我们先找出生日日期相同的人,在对其进行名字的排序,可能会十分复杂,所以我们可以先对其名字进行排序,再从中抽出日期相同的人,这样当我们抽出来的时候他们的名字就是已序的啦!
同时这题还有另一大难点,就是寻找日期相同的人,如果我们用暴力搜索的话,很大概率会时间超限,那么我们必须就要改变方法
还记得之前160题时候的字符串么,我运用到了桶的方法,这题也同样,但是日期怎么放入桶中呢。其实也很简单,用二维数组就好啦!
点击查看代码
#include<stdio.h>
#include<string.h>
struct stu
{
char name[20];
int m;
int d;
};
int main()
{
struct stu a[180];
int n;
int b[32][32] = { 0 };
char c[20];
int i;
int t;
int j;
int k;
scanf("%d\n", &n);
for (i = 1; i <= n; i++)
{
scanf("%s %d %d\n", a[i].name, &a[i].m, &a[i].d);
}
for (i = 0; i <= n; i++)//按照名字的要求进行排序
{
for (j = i; j < n; j++)
{
if (strlen(a[i].name) > strlen(a[j].name))
{
strcpy(c, a[i].name);
strcpy(a[i].name, a[j].name);
strcpy(a[j].name, c);
t = a[i].m;
a[i].m = a[j].m;
a[j].m = t;
t = a[i].d;
a[i].d = a[j].d;
a[j].d = t;
}
else if (strlen(a[i].name) == strlen(a[j].name))
{
if (strcmp(a[i].name,a[j].name)>0)
{
strcpy(c, a[i].name);
strcpy(a[i].name, a[j].name);
strcpy(a[j].name, c);
t = a[i].m;
a[i].m = a[j].m;
a[j].m = t;
t = a[i].d;
a[i].d = a[j].d;
a[j].d = t;
}
}
}
}
for (i = 0; i < n; i++)//利用桶来记录每个日记有多少人生日
{
b[a[i].m][a[i].d]++;
}
int f = 0;
for (i = 1; i <= 12; i++)
{
for (j = 1; j <= 31; j++)
{
if (b[i][j] > 1)//若大于1,则可以输出对应名字
{
printf("%d %d", i, j);
f = 1;
for (k = 0; k < n; k++)//顺序查找,那么经过之前的排序,我们就可以直接对应输出名字已经排好序的人啦
{
if (a[k].m == i && a[k].d == j)
{
printf(" %s", a[k].name);
}
}
printf("\n");
}
}
}
if (f == 0)//若没有一个二维数组上的数大于1,则没有生日相同的人
{
printf("None\n");
}
}