L2-034 口罩发放 (25 分)
为了抗击来势汹汹的 COVID19 新型冠状病毒,全国各地均启动了各项措施控制疫情发展,其中一个重要的环节是口罩的发放。
某市出于给市民发放口罩的需要,推出了一款小程序让市民填写信息,方便工作的开展。小程序收集了各种信息,包括市民的姓名、身份证、身体情况、提交时间等,但因为数据量太大,需要根据一定规则进行筛选和处理,请你编写程序,按照给定规则输出口罩的寄送名单。
/*
结构体存储每天的数据;
vector<>存储发烧人员
map<string,int>对人员id进行标记(身份证唯一性)
用m1,m2,一个标记有收到口罩的人
一个标记发烧人员的输出
具体看代码解析
*/
#include<bits/stdc++.h>
using namespace std;
bool Panduan(string s)//判断身份证信息
{
int length=s.size();
if(length!=18) return false;//是不是18位
else
{
for(int i=0;i<18;i++)
{
if(s[i]<'0'||s[i]>'9')//是不是都是数字
{
return false;
}
}
}
return true;
}
struct P{
string Name;
string Id;
int status;
int hh,mm;//时间 (排序)
int num;//登记的序号 (排序)
};
vector<struct P> v;//存储发烧的人员
bool cmp(struct P a,struct P b)//对时间进行排序
{
if(a.hh!=b.hh) return a.hh <b.hh ;
else if(a.mm!=b.mm) return a.mm<b.mm;
else return a.num<b.num;
}
int main(void)
{
int n,m;//天数、间隔
cin>>n>>m;
int x,y;//人数、口罩数
map<string,int> m1,m2;//m1记录人发放时间间隔、m2标记发烧人的输出(每人仅输出一次)
for(int i=1;i<=n;i++)
{
cin>>x>>y;
struct P p[x];//存储每天符合格式的人 (也可以用vector)
int s=0;//记录能发口罩的人数
for(int j=0;j<x;j++)
{
string name,id;
int status,hh,mm;
cin>>name>>id>>status;
getchar();
scanf("%d:%d",&hh,&mm);
if(!Panduan(id)) continue;//Id错误,不记录
else
{
p[s].Name=name;
p[s].Id=id;
p[s].status=status;
p[s].hh=hh;
p[s].mm=mm;
p[s].num=s;
if(status==1) v.push_back(p[s]);//记录发烧的
s++;//人员++
}
}
sort(p,p+s,cmp);//对排队时间进行排序
//我没有把所有发放记录都记录
//而是当天发口罩就当天输出发放记录
for(int j=0;j<s&&y>0;j++)//按条件发口罩
{ //要么一次没发过,要么发过了要间隔 m 天
if(m1[p[j].Id]==0||m1[p[j].Id]+m+1<=i)
{
cout<<p[j].Name<<" "<<p[j].Id<<endl;
y--;//口罩--
m1[p[j].Id]=i;//给谁发口罩就记录日期
}
}
}
//用map<string ,int> m2进行输出标记
for(auto & it:v)//输出发烧的人
{
if(m2[it.Id]!=0) continue;//输出过了就跳过
else
{
cout<<it.Name<<" "<<it.Id<<endl;
m2[it.Id]++;//只要没输出,就++
}
}
return 0;
}
以上代码是测试点都过了。
但是我有一个疑惑:本来我的cmp函数是这么写的
bool cmp(struct P a,struct P b)//对时间进行排序
{
if(a.hh!=b.hh) return a.hh <b.hh ;
else return a.mm<b.mm;
}
但是测试点4,5过不了。
我以为sort对struct进行排序的时候,如果时间相等的话,那么他也不会对源数据的顺序进行修改。于是我写了测试代码,如下:
/*
用sort进行排序时,在不符合排序规则的情况下
会改本原本数组的顺序吗?
下列的程序中,当a,b的值相等时,并不会改变原本
数据的前后关系。
*/
#include<iostream>
#include<bits/stdc++.h>
using namespace std;
struct P{
int num;
int a,b,c;
}p[100];
bool cmp(struct P x,struct P y)
{
if(x.a!=y.a ) return x.a <y.a ;
else return x.b<y.b;
}
int main(void)
{
for(int i=0;i<6;i++)
{
p[i].num=i;
cin>>p[i].a>>p[i].b>>p[i].c;
}
sort(p,p+6,cmp);
for(int i=0;i<6;i++)
{
cout<<p[i].num<<' '<<p[i].a<<' '<<p[i].b<<" "<<p[i].c<<endl;
}
return 0;
}
/*
2 4 7
2 4 5
2 4 8
2 4 6
2 4 9
2 4 0
*/
结果显示,确实不会对源数据进行修改。
那么我这个排序明显也符合题目规定的“如果提交时间相同,则按照在列表中出现的先后顺序决定。”这个要求,那为什么测试点4 ,5过不了呢?
如果有知道的大神,望告知。