PTA L2-034 口罩发放 (25 分)

题目地址

L2-034 口罩发放 (25 分)

测试点(记录一下我遇到的坑)

1.测试点4和测试点5的提交时间一样,卡排队顺序。
2.有合法记录的、身体状况为 1 的申请人必须全部存下来,输出时再判重,不可以set直接存放判重,否则卡4.5.6测试点。
在这里插入图片描述

AC代码

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <map>
#include <vector>
#include <set>

using namespace std;

typedef pair<string, string> PSS;

struct Node
{
    char name[15];  // 名字
    char id[20];    // 身份证
    int state;      // 状态
    int time;       // 申请提交时间
    int pos;        // 排队序号
};

int d, p; // d天信息、间隔p天
map<string, int> mp; // 同一个id在第几天领取成功过、0表示没领取过
vector<Node> v; // 存放每天的有效申请信息(身份证合法)
vector<PSS> peo; // 身体状况为1的人都要存下来,输出时再判重(卡后三测试点)
set<PSS> S; // 输出时用于判重,患病信息是否输出过

bool check(char id[]) // 检查身份证是否合法
{
    int len = strlen(id);
    if (len != 18) return false;
    else
    {
        for (int i = 0; i < len; i++)
            if (id[i] < '0' || id[i] > '9')
                return false;
    }
    return true;
}

bool cmp(Node a, Node b)
{
    if (a.time != b.time) return a.time < b.time;
    return a.pos < b.pos;
}

int main()
{
    scanf("%d%d", &d, &p);
    for (int i = 1; i <= d; i++) // 第i天
    {
        int t, s; // 申请、名额
        scanf("%d%d", &t, &s);
        v.clear(); // 把前一天的信息清空、只存当天的提交申请信息
        
        Node node;
        int hh, mm;
        for (int j = 1; j <= t; j++) // 第j条申请信息
        {
            scanf("%s %s %d %d:%d", node.name, node.id, &node.state, &hh, &mm);
            node.time = hh * 60 + mm;
            node.pos = j;
            if (check(node.id)) // 身份证合法
            {
                string str = node.id; // 将char转为string
                if (!mp[str] || mp[str] + p < i) // 没领过或时间够了
                    v.push_back(node);
                if (node.state) // 存下身体状况为1的人
                {
                    string str1 = node.name, str2 = node.id;
                    peo.push_back({str1, str2}); // 先存下来,最后判重
                }
            }
        }
        
        sort(v.begin(), v.end(), cmp);
        
        for (int j = 0; j < (int)v.size(); j++) // 输出当天可以领到口罩的人
        {
            string str = v[j].id;
            if (!s) break; // 没口罩了
            if (!mp[str] || mp[str] + p < i) // 满足条件
            {
                printf("%s %s\n", v[j].name, v[j].id);
                mp[str] = i; // 标记为第i天领取过
                s--;
            }
        }
    }
    
    // 不能用set直接存状态为1的人,必须输出的时候才判重(后三个测试点)
    for (int i = 0; i < (int)peo.size(); i++)
    {
        if (!S.count(peo[i])) // 没输出过
        {
            printf("%s %s\n", peo[i].first.c_str(), peo[i].second.c_str());
            S.insert(peo[i]);
        }
    }
    
    return 0;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值