L2-034 口罩发放(2020天梯赛) 难点逐一分析攻克

目录

一、题目

二、分析

1、检验身份证是否合法(身份证号必须是18位的数字且可以包含前导0)

2、判断本次口罩发放与上次领取的间隔时间是否合法

3、排序(按照提交时间的先后顺序发放)

4、时间输入

三、代码


一、题目

PTA口罩发放

二、分析

1、检验身份证是否合法(身份证号必须是18位的数字且可以包含前导0)

bool test(string str)
{
    if(str.size()!=0)
        return false;
    for(int i=0;i<18;i++)
        if(str[i]<'0'||str[i]>'9')
            return false;
    return true;
}

2、判断本次口罩发放与上次领取的间隔时间是否合法

(同一个身份证号若在第 i 天申请成功,则接下来的 P 天不能再次申请。)

使用STL中的map将身份证号映射一个整数,该整数表示上次领取的口罩为第几天

map<string,int> M;

if(当前天数-M[身份证]>=P+1)
{
    满足;
}

3、排序(按照提交时间的先后顺序发放)

定义结构体封装每条申请信息,按照小时、分钟、输入顺序进行排序

排序使用STL-sort + 自定义比较函数

bool cmp(node x1,node x2)
{
    if(x1.h==x2.h)
    {
        if(x1.m==x2.m)
            return x1.id<x2.id;
        return x1.m<x2.m;
    }
    return x1.h<x2.h;
}

sort(e+1,e+1+t,cmp);

4、时间输入

scanf("%d:%d",&e[j].h,&e[j].m);

三、代码

#include<bits/stdc++.h>
using namespace std;
const int N=30010;

struct node
{
    int id;
    string name;
    string sfz;//身份证
    int stqk;//身体健康情况
    int h,m;
    bool st;//身份证是否合法
}E[N];
map<string,int> M;
int idx;


bool cmp(node x1,node x2)
{
    if(x1.h==x2.h)
    {
        if(x1.m==x2.m)
            return x1.id<x2.id;
        return x1.m<x2.m;
    }
    return x1.h<x2.h;
}

bool test(string op)
{
    if(op.size()!=18)   
        return false;
    for(int i=0;i<18;i++)
        if(op[i]<'0'||op[i]>'9')
            return false;
    return true;
}

int main()
{
    int D,P;
    cin>>D>>P;
    for(int i=1;i<=D;i++)
    {
        int t,s;
        cin>>t>>s;
        node e[t+10];
        for(int j=1;j<=t;j++)
        {
            cin>>e[j].name>>e[j].sfz>>e[j].stqk;
            scanf("%d:%d",&e[j].h,&e[j].m);
			e[j].id=j;
            e[j].st=test(e[j].sfz);
            if(e[j].stqk&&e[j].st)
                E[idx++]=e[j];
        }
        sort(e+1,e+1+t,cmp);
        for(int j=1;j<=t&&s;j++)
        {
            if(M[e[j].sfz]==0)
                M[e[j].sfz]=-2*P;
            if(e[j].st&&(i-M[e[j].sfz]>=P+1))
            {
                cout<<e[j].name<<" "<<e[j].sfz<<endl;
                M[e[j].sfz]=i;
                s--;
            }
        }
    }

    for(int i=0;i<idx;i++)
    {
        if(M[E[i].sfz]!=-1)
        {
            cout<<E[i].name<<" "<<E[i].sfz<<endl;
            M[E[i].sfz]=-1;
        }    
    }

    return 0;
}

  • 8
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值