题意
给D天,和获得口罩的间隔时间至少P天。接下来是第i天有ti条申请,但名额只有si个,接下来ti行是申请信息,要求判断每天可以获得口罩的人信息并按顺序输出
思路
1.利用结构体存放信息,排序先按时间后按申请表的顺序
2.因为前一次申请成功的时间是确定的,利用map存放申请成功时间,用于判断是否已经经 过P天
3.判断身份证是否合理
4.依次输出满足要求申请成功的信息,最后将身体情况为1的输出
坑点
1.下一次拿口罩的时间是p+i+1天
2.身体情况为1 的不能重复输出
代码
#include<bits/stdc++.h>
using namespace std;
struct name
{
string name;//姓名
string id;//身份证号
int body;//身体状况
string time;//领取时间
int xu;//顺序
}a[30010],b[30010];//全部,病人
bool cmp(name x,name y)
{
if(x.time!=y.time)//时间不等时
{
return x.time<y.time;//时间升序排
}
else//相等时
{
return x.xu<y.xu;//顺序升序排
}
}
bool check(string id)//身份证满足18位的数字
{
if(id.size()!=18)//判断是否是18位
{
return false;//不是则不满足条件
}
for(int i=0;i<18;i++)//满足的话
{
if(id[i]<'0'||id[i]>'9')//再次判断是否是>=0 并且,<=9 的数
{
return false;//不是则不满足
}
}
return true;//均满足则返回true
}
map<string,int>mp;
map<string,int>mp2;
int main()
{
int d,p;
cin>>d>>p;//d天,间隔天数p
int t,s;
int sum=0;//病人数
for(int i=1;i<=d;i++)
{
cin>>t>>s;//读入领取人数t和领取上限为s
for(int j=1;j<=t;j++)//遍历人数
{
cin>>a[j].name>>a[j].id>>a[j].body>>a[j].time;//依次读入人的姓名、身份证号、身体状况、领取时间
a[j].xu=j;//顺序即遍历顺序
}
for(int j=1;j<=t;j++)//病 人
{
if(check(a[j].id)!=true)//检测人的身份证号是否正确
{
continue;//正确则继续
}
if(a[j].body==1&&mp[a[j].id]==0)//一天不重复出现的病人
{
mp[a[j].id]=1;//赋值为1 ,只出现过一次
sum++;//计算可领取的人数
b[sum].name=a[j].name;//领取的人的姓名等于读入的人姓名
b[sum].id=a[j].id;//身份证号也一样
}
}
sort(a+1,a+1+t,cmp);//结构体排序
int ren=0;//正常人
for(int j=1;j<=t;j++)//全部
{
if(check(a[j].id)!=true)//证号正确
{
continue;//继续
}
if(ren<s)//正常人小于 上限
{
if(mp2[a[j].id]==0||mp2[a[j].id]+p+1<=i)//当天不重复哪或过了p+i+1天来
{
mp2[a[j].id]=i;//领过,第几天领的
ren++;//计数
cout<<a[j].name<<" "<<a[j].id<<endl;//输出可领取人的姓名和证号
}
}
}
}
for(int k=1;k<=sum;k++)
{
cout<<b[k].name<<" "<<b[k].id<<endl;//输出病人可领取的姓名和证号
}
return 0;
}
总结
理清思路,进行模拟