2020年天梯賽真題——L2-2 口罩發放
為了抗擊來勢洶洶的 COVID19 新型冠狀病毒,全國各地均啟動了各項措施控制疫情發展,其中一個重要的環節是口罩的發放。
某市出於給市民發放口罩的需要,推出了一款小程式讓市民填寫資訊,方便工作的開展。小程式收集了各種資訊,包括市民的姓名、身份證、身體情況、提交時間等,但因為資料量太大,需要根據一定規則進行篩選和處理,請你編寫程式,按照給定規則輸出口罩的寄送名單。
輸入格式:
輸入第一行是兩個正整數 D 和 P(1≤D,P≤30),表示有 D 天的資料,市民兩次獲得口罩的時間至少需要間隔 P 天。
接下來 D 塊資料,每塊給出一天的申請資訊。第 i 塊資料(i=1,⋯,D)的第一行是兩個整數 T
和 S
i
(1≤T
i
,S
i
≤1000),表示在第 i 天有 T
i
條申請,總共有 S
i
個口罩發放名額。隨後 T
i
行,每行給出一條申請資訊,格式如下:
姓名 身份證號 身體情況 提交時間
給定資料約束如下:
姓名 是一個長度不超過 10 的不包含空格的非空字串;
身份證號 是一個長度不超過 20 的非空字串;
身體情況 是 0 或者 1,0 表示自覺良好,1 表示有相關症狀;
提交時間 是 hh:mm,為24小時時間(由 00:00 到 23:59。例如 09:08。)。注意,給定的記錄的提交時間不一定有序;
身份證號 各不相同,同一個身份證號被認為是同一個人,資料保證同一個身份證號姓名是相同的。
身份證號 必須是 18 位的數字(可以包含前導0);
同一個身份證號若在第 i 天申請成功,則接下來的 P 天不能再次申請。也就是說,若第 i 天申請成功,則等到第 i+P+1 天才能再次申請;
在上面兩條都符合的情況下,按照提交時間的先後順序發放,直至全部記錄處理完畢或 S
i
個名額用完。如果提交時間相同,則按照在列表中出現的先後順序決定。
輸出格式:
對於每一天的申請記錄,每行輸出一位得到口罩的人的姓名及身份證號,用一個空格隔開。順序按照發放順序確定。
在輸出完發放記錄後,你還需要輸出有合法記錄的、身體狀況為 1 的申請人的姓名及身份證號,用空格隔開。順序按照申請記錄中出現的順序確定,同一個人只需要輸出一次。
輸入樣例:
4 2
5 3
A 123456789012345670 1 13:58
B 123456789012345671 0 13:58
C 12345678901234567 0 13:22
D 123456789012345672 0 03:24
C 123456789012345673 0 13:59
4 3
A 123456789012345670 1 13:58
E 123456789012345674 0 13:59
C 123456789012345673 0 13:59
F F 0 14:00
1 3
E 123456789012345674 1 13:58
1 1
A 123456789012345670 0 14:11
輸出樣例:
D 123456789012345672
A 123456789012345670
B 123456789012345671
E 123456789012345674
C 123456789012345673
A 123456789012345670
A 123456789012345670
E 123456789012345674
樣例解釋:
輸出中,第一行到第三行是第一天的部分;第四、五行是第二天的部分;第三天沒有符合要求的市民;第六行是第四天的部分。最後兩行按照出現順序輸出了可能存在身體不適的人員。
思路
簡直快吐了的一道題,程式碼很好寫,但是一直答案錯誤
我特別想知道是過了一個測試點還是全錯了,但是這個題目集看不了。。。。。
最後沒辦法只能百度
AC程式碼
#include<bits/stdc++.h>
using namespace std;
typedef struct Node{
string name;
string id;
int flag;
int hh,mm;
int t;
int idx;
}mm;
int cmp(mm a,mm b){
if(a.t!=b.t) return a.t<b.t;
else return a.idx<b.idx;
}
int Judge(string s){
if(s.size()!=18) return 0;
for(int i=0;i<s.size();i++){
if(!isdigit(s[i])) return 0;
}
return 1;
}
int main(){
int d,p,t,s,cnt=0;
mm xx[10001],xx1[10001];
map<string,int> mp;
map<string,int> vis;
cin>>d>>p;
for(int i=1;i<=d;i++){
cin>>t>>s;
for(int j=1;j<=t;j++){
cin>>xx[j].name>>xx[j].id>>xx[j].flag;
scanf("%d:%d",&xx[j].hh,&xx[j].mm);
xx[j].t=xx[j].hh*60+xx[j].mm;
xx[j].idx=j;
if(mp.find(xx[j].id)==mp.end()) mp[xx[j].id]=0;
if(xx[j].flag==1&&Judge(xx[j].id)&&vis.find(xx[j].id)==vis.end()){
vis[xx[j].id]=0;
xx1[cnt++]=xx[j];
}
}
sort(xx+1,xx+t+1,cmp);
for(int j=1,q=0;j<=t&&q<s;j++){//發放口罩
if(Judge(xx[j].id)&&(!mp[xx[j].id]||i-mp[xx[j].id]>p)){//未發放過的或者已發放過過了p天的
cout<<xx[j].name<<" "<<xx[j].id<<endl;
q++;
mp[xx[j].id]=i;
}
}
}
for(int i=0;i<cnt;i++)
cout<<xx1[i].name<<" "<<xx1[i].id<<endl;
return 0;
}
啊啊啊啊,哪位大神幫忙找找錯啊啊啊啊啊啊
錯誤程式碼
#include<bits/stdc++.h>
using namespace std;
typedef struct stu{
string name;
string id;
int flag;
int idx;
int time;
int num=0;//天數
}mm;
int Judge(mm x){//判斷是否合格
string s=x.id;
if(s.size()!=18) return 0;
for(int i=0;i<s.size();i++){
if(!isdigit(s[i])) return 0;
}
return 1;
}
int cmp(mm a,mm b){
if(a.time!=b.time)
return a.time<b.time;
else return a.idx<b.idx;
}
int main(){
int d,p,t,s,hh1,mm1;
cin>>d>>p;
map<string,int> xx1p,xx2;//xx1p:有合法記錄身體狀況為1的人;xx2:判斷申請成功了幾次
vector<mm> xx1;
for(int i=0;i<d;i++){
cin>>t>>s;//t條申請,s個口罩
vector<mm> xx;
for(int j=0;j<t;j++){
mm x;
cin>>x.name>>x.id>>x.flag;
scanf("%d:%d",&hh1,&mm1);
x.time=hh1*60+mm1;
x.idx=j;
if(Judge(x)){//記錄合法
if(x.flag&&xx1p[x.id]==0){//身體狀況為1 ,且未被計入
xx1.push_back(x);
xx1p[x.id]=1;
}
if(xx2[x.id]==0)//申請成功
xx.push_back(x);
}
}
for(auto it=xx2.begin();it!=xx2.end();it++){
if(it->second) it->second=it->second-1;
}
sort(xx.begin(),xx.end(),cmp);
int min=s<xx.size()?s:xx.size();
for(int j=0;j<min;j++){
cout<<xx[j].name<<" "<<xx[j].id<<endl;
xx2[xx[j].id]=p;//申請成功,開始計時
}
}
for(int j=0;j<xx1.size();j++){
cout<<xx1[j].name<<" "<<xx1[j].id<<endl;
}
return 0;
}