一道究极恶心的模拟题
需要注意的点:
身份证号
必须是 18 位的数字(可以包含前导0):这句话的意思不仅仅是身份证必须是18位的,还必须是数字- 同一个身份证号若在第 i 天申请成功,则接下来的 P 天不能再次申请:我们需要记录每个人上一次申请的时间(但这里也有可能陷入一个误区)
- 按照提交时间的先后顺序发放,直至全部记录处理完毕或 Si 个名额用完。如果提交时间相同,则按照在列表中出现的先后顺序决定:这句话包含了两个意思:先按照时间顺序排序处理申请,如果时间相同,按照申请记录中出现的顺序确定。
在输出完发放记录后,你还需要输出有合法记录的、身体状况为 1 的申请人的姓名及身份证号,用空格隔开。顺序按照申请记录中出现的顺序确定,同一个人只需要输出一次:注意这里是按照申请出现的顺序,而不是时间顺序
点2的误区:
我在结构体中定义了一个整数型last,用来记录每一个人上次申请的时间,并设置last的初始值是-1,当申请合法时,就修改last的值。看起来没有问题,但我们忽略了一个点,我们每一次输入t个申请都是生成了t个新的结构体节点,每一个结构体节点的last都是-1,尽管我们可以修改了last的值,但我们在下一次输入的时候last仍然为-1。也就是说,我们上一次修改的值不会影响到下一次这个人的last值,即,last是一个局部变量,所以我们要设置一个全局变量,来标记last的值,也就是map了。
关于点3排序:
我们用自己定义的cmp函数对结构体排序时,不能百分之百保证时间相同时,排序是按照申请出现的顺序来的,所以保险起见,我们给每一个节点标记一个优先级就可以了。
点4:
活该不认真读题!
另外
对于同类型(同结构体类型node)的两个结构体节点i和j,我们可以直接让node[i]=node[j]给i赋值,而不是繁琐的node[i].x=node[j].x, node[i].y=node[j].y...........
AC代码
// 0
#include <iostream>
#include <cstring>
#include <algorithm>
#include <set>
#include <map>
using namespace std;
const int N = 10010;
int n, m, k, idx;
struct Node{
char name[100];//结构体中最好别用string
char num[20];
int flag;
int h, m;
int pid; //标记一个优先级
};
Node node[N], res[N];
set<string> s, hurt;
map<string, int> si;
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.pid < y.pid; //一个点
}
bool check(char ch[])
{
if(strlen(ch) != 18) return false;
for(int i = 0; i < 18; i ++ ) //身份证号必须是数字!
{
if(ch[i] >= '0' && ch[i] <= '9') continue;
else return false;
}
return true;
}
int main()
{
cin >> n >> m;
for(int i = 1; i <= n; i ++ )
{
int t, maxn, now = 0;
cin >> t >> maxn;
for(int j = 0; j < t; j ++ )
{
node[j].pid = j;
scanf("%s %s %d %d:%d", node[j].name, node[j].num, &node[j].flag, &node[j].h, &node[j].m);
if(check(node[j].num) && node[j].flag && !hurt.count(node[j].num))//这里也要对身份证的合法性判断一下
{
res[idx ++ ] = node[j];
hurt.insert(node[j].num);
}
}
sort(node, node + t, cmp);
// cout << "node: " << endl;
// for(int j = 0; j < t; j ++ )
// printf("%s %s %d %d:%d\n", node[j].name, node[j].num, node[j].flag, node[j].h, node[j].m);
for(int j = 0; j < t; j ++ )
{
if(!check(node[j].num)) continue;
if(s.count(node[j].num))
{
if(now < maxn && (si[node[j].num] == 0 || i >= si[node[j].num] + m + 1))
{
now ++ ;
si[node[j].num] = i;
printf("%s %s\n", node[j].name, node[j].num);
}
}
else
{
if(now < maxn)
{
s.insert(node[j].num);
now ++ ;
si[node[j].num] = i;
printf("%s %s\n", node[j].name, node[j].num);
}
}
}
}
// cout << idx << endl;
for(int i = 0; i < idx; i ++ )
printf("%s %s\n", res[i].name, res[i].num);
return 0;
}