生日相同问题
问题描述:
在一个有n个学生的大班级中,存在两个学生生日相同的概率非常大,现在给出每个学生的名字,出生日月,试找出所有生日相同的学生
输入格式:
第一行为n个整数,表示有n个学生,n<=180;
此后n行,每行包含一个字符串和两个正整数,分别表示学生的名字(名字第一个字母大写,其余小写,不含空格,且长度小于20),和出生月m、出生日d,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
问题分析
首先创建一个长度为n的数组和结构体stu
利用动态分配内存减少静态内存分布的损耗空间
创建12个月每个月30天一共360个桶
遍历数组,当有相同日期的学生就放入桶
mark用于标记桶里元素的数量
如果桶中有2名学生或以上则输出
用bl来标记所有学生中是否有一样生日的
否则输出None
实现代码
#include<iostream>
#include<string.h>
using namespace std;
//输出函数
void printName(string* nameTemp, int mark) {
//冒泡排序
for (int i = 0;i <= mark;i++) {
for (int j = 1;j <= mark;j++) {
//用compare比较两个字符串的大小
int temp = nameTemp[i].compare(nameTemp[j]);
if (temp > 0) {
string temp = nameTemp[i];
nameTemp[i] = nameTemp[j];
nameTemp[j] = temp;
}
}
}
for (int k = 0;k <= mark;k++) {
cout << nameTemp[k]<<" ";
}
};
struct stu {
int m, d;
string name;
//输入函数
void input() {
cin >> name >> m >> d;
}
};
int main() {
int n;
cin >> n;
stu* a;
a = new stu[n + 1];//动态分配内存
string* nameTemp;
nameTemp = new string[n + 1];//动态分配内存
for (int i = 1;i <= n;i++) {
a[i].input();
}
bool bl = false;
//构建360个桶来装学生
for (int month = 1;month <= 12;month++) {
for (int date = 1;date <= 30;date++) {
int mark = 0;
for (int j = 1;j <= n;j++) {
//mark标记用于记录桶内人数
if (date == a[j].d && month == a[j].m) {
nameTemp[mark] = a[j].name;
mark++;
}
}
//如果mark标记大于1,则输出桶内元素
if (mark >1) {
cout << endl << month << " " << date << " ";
printName(nameTemp,mark);
bl = true;
}
nameTemp->clear();//每次循环清除newTemp
}
}
//如果没有生日相同的学生,输出None
if (bl == false) {
cout << "None" << endl;
}
return 0;
}