程序设计天梯赛 L2-034 口罩发放

问题遇到的现象和发生背景

https://pintia.cn/problem-sets/994805046380707840/problems/1336215880692482057
可以通过测试用例但提交只有5分

问题相关代码,请勿粘贴截图
#include <bits/stdc++.h>
using namespace std;

struct P
{
    string name;    //姓名 
    string id;        //身份证号 
    int health;        //健康状况 
    int day;        //上次领取的日期 
    int time;         //填表时间 
};

P p[50000];
map <string, int> m;    //<id, index>    用id来对应某人在p中的下标indedx 
int D,d;

//check身份证号码 
bool check(string id)
{
    if(id.length()!=18)
        return false;
    for(int i=0;i<id.size();i++)
        if(id[i] > '9' || id[i] < '0')
            return false;
    return true;        
}


bool cmp(P p1,P p2)
{
    return p1.time < p2.time;
}


int main()
{
    cin>>D>>d;
    int index=0;        //下标从0开始 
    for(int i=1;i<=D;i++)
    {
        int n,me;
        cin>>n>>me;            //me是当日名额 
        vector<P > temp;        //暂存当日参与竞争的人 
        temp.clear();
        while(n--)
        {
            string name;
            string id;
            int health;
            int hh,mm; 
            int time;
            char sep;
            cin>>name>>id>>health;
            cin>>hh>>sep>>mm; 
            time=hh+60*mm;        //转换为分钟数 

            if(!check(id))        //若身份证不合法则跳过 
                continue;
                
            
            P pt={name,id,health,i,time};    //将某人信息打包 

            
            if(m.find(id)==m.end())        //若map中未找到id,则表示第一次来 
            {
                m.insert(make_pair(id,index));    //为此人创建index 
                p[index]=pt;                            //复制数据 
                p[index].day=0;                    //注意!此时还没发口罩,day先为0 
                temp.push_back(pt);                //新来的人可以参与竞争,放入temp 
                index++;
            }
            
            //不是新来的 
            else if(i - p[m[id]].day > d || p[m[id]].day==0)    //若距离上一次领口罩很久了 或 还没领过口罩 
            {
                
                //查找有无一天填写多次的人 
                bool flag=0;
                vector <P > :: iterator it;
                for(it=temp.begin();it!=temp.end();it++)
                {
                    if(it->id == pt.id)
                        flag=1;
                } 
                if(!flag)                //未出现重复 
                    temp.push_back(pt);      //有资格参与竞争 放入temp 
            } 
            if(health==1)                        //发热一定要报备 ,每次来都得检查
                p[m[id]].health=health;            //只要发热过,health就要置1     
        }
        
        sort(temp.begin(),temp.end(),cmp);        //对temp排序,以时间升序 
        
        for(int j=0;j<temp.size();j++)    //按排名取优先者 
        {
            if(j>me-1)    break;                            //当心访问越界 
            p[m[temp[j].id]].day=temp[j].day;            //已领取口罩,更新状态(打上时间戳) 
            cout<<temp[j].name<<" "<<temp[j].id<<endl;    //输出 
        }        
    }


    //输出发热过的人    
    for(int i=0;i<50000;i++)
    {
        if(p[i].health==1)
            cout<<p[i].name<<" "<<p[i].id<<endl;
    }    
    
}

运行结果及报错内容

测试用例暂无报错

我的解答思路和尝试过的方法

思路见注释

我想要达到的结果

25分

坑点
s可能为0, 口罩没有名额
同一天,一个人可能申请多次!!
输出身体状况为 1 的人是,只要这个人的ID合法且为1,就要存下来输出,顺序按照输入的顺序
检查ID是否合法,不仅要判断是否为18位,还要判断每一位是否都是数字


#include<bits/stdc++.h>
using namespace std;
struct Node {
    string name,id;
    int zk;
    int h,m;
    int ii;
};
vector<Node>v;//记录有合法记录的、身体状况为 1 的申请人 
map<string,int>mp1,mp2;//mp1记录最近申请成功时间  mp2去重 
int check(string s) {//判断id是否合格 
    int l=s.length(),f=0;
    for(int i=0; i<l; i++) {
        if(s[i]<'0'||s[i]>'9') {
            f=1;
            break;
        }
    }
    if(f==0&&l==18) {
        return 1;
    } else {
        return 0;
    }
}
bool cmp(Node x,Node y) {//按时间-出现次序排序 
    if(x.h!=y.h) {
        return x.h<y.h;
    } else if(x.m!=y.m) {
        return x.m<y.m;
    } else {
        return x.ii<y.ii;
    }
}
int main() {
    int d,p;
    cin>>d>>p;
    for(int i=1; i<=d; i++) {
        int t,s;
        Node r[1005];
        cin>>t>>s;
        for(int j=1; j<=t; j++) {
            r[j].ii=j;
            cin>>r[j].name>>r[j].id>>r[j].zk;
            scanf("%2d:%2d",&r[j].h,&r[j].m);
            // 有合法记录的、身体状况为 1 的申请人按列表次序输出 
            if(check(r[j].id)&&r[j].zk==1&&!mp2[r[j].id]) {
                v.push_back(r[j]);
                mp2[r[j].id]=1;
            }
        }
        //能发放口罩的记录按时间-列表次序输出 
        sort(r+1,r+1+t,cmp);
        for(int j=1; j<=t; j++) {
            if(check(r[j].id)) {
                if(s&&(!mp1[r[j].id]||i-mp1[r[j].id]>p)) {
                    s--;
                    mp1[r[j].id]=i;
                    cout<<r[j].name<<" "<<r[j].id<<endl;
                }
            }
        }

    }
    for(int i=0; i<v.size(); i++) {
        cout<<v[i].name<<" "<<v[i].id<<endl;
    }
    return 0;
}



```c++

#pragma GCC optimize(2)
#include<bits/stdc++.h>
#define rep1(i,a,n) for( int i=(a);i<(n);++i) 
#define rep2(i,a,n) for( int i=(a);i<=(n);++i) 
#define per1(i,n,a) for( int i=(n);i>(a);i--) 
#define per2(i,n,a) for( int i=(n);i>=(a);i--)
#define quick_cin() cin.tie(0),cout.tie(0),ios::sync_with_stdio(false)
#define memset(a,i,b) memset((a),(i),sizeof (b))
#define endl "\n"
#define lowbit(m) ((-m)&(m))
#define dbug(y) cout<<(y)<<"\n"
#define dbug2(a,b) cout<<(a)<<" "<<(b)<<"\n"
#define dbug3(a,b,c) cout<<(a)<<" "<<(b)<<" "<<(c)<<"\n"
#define dbug4(a,b,c,d) cout<<(a)<<" "<<(b)<<" "<<(c)<<" "<<(d)<<"\n"
#define tulun int e[N],ne[N],h[N],w[N],idx;
#define add2(a,b) e[idx]=b,ne[idx]=h[a],h[a]=idx++;
#define add3(a,b,c) w[idx]=c,e[idx]=b,ne[idx]=h[a],h[a]=idx++;
#define T_solve() int T;cin>>T;while(T--)solve();
#define pi 3.14159265358979323846
using namespace std;
typedef long long LL;
typedef pair<int,int> PII;
typedef pair<long long,long long> PLL;
typedef double dob;
const int N=1e5+10;
#define inf 0x3f3f3f3f3f3f3f3f
int D,p;
int n,s;
struct node
{
    string name,id,sj;
    int healh,num;
    bool operator<(const node &cc)const{
        if(sj!=cc.sj)return sj<cc.sj;
        else return num<cc.num;
    }
}a[1010];
struct node2
{
    string name,id;
};
unordered_map<string,int>hs[100];
unordered_map<string,int>hs2;
vector<node2>xl2;
int ok(string s)//判断id是否合法;
{
    int siz=s.size();
    if(siz!=18)return 0;
    rep1(i,0,18)
    {
        if(!isdigit(s[i]))return 0;
    }
    return 1;
}
void solve(int day)
{
    cin>>n>>s;
    rep2(i,1,n)
    {
        a[i].num=i;
        cin>>a[i].name>>a[i].id>>a[i].healh>>a[i].sj;
        if(ok(a[i].id)&&a[i].healh)//根据申请顺序确定输出发烧的人的列表
        xl2.emplace_back((node2){a[i].name,a[i].id});
    }
    sort(a+1,a+n+1);
    rep2(i,1,n)
    {
        if(s>0&&ok(a[i].id)&&hs[day][a[i].id]==0)//有口罩余额,id合法,且满足一段时间未申请;
        {
            dbug2(a[i].name,a[i].id);
            s--;
            rep2(j,day,day+p)hs[j][a[i].id]=1;
        }
    }
}
signed main()    
{
    quick_cin();

    cin>>D>>p;
    rep2(i,1,D)solve(i);
    for(auto &i:xl2)
    {
        if(!hs2[i.id])//同一个人只输出一次
        {
            dbug2(i.name,i.id);
            hs2[i.id]=1;
        }
    }
    return 0;
}
//

```