TOJ3216 我要4444
传送门 http://acm.tzc.edu.cn/acmhome/problemdetail.do?&method=showdetail&id=3216
时间限制(普通/Java):1000MS/3000MS 内存限制:65536KByte
描述
M国的车牌号只有4位,别人都很想要8888,6666,3333等,但是Mr.L很奇怪,他想要4444……
M国的车牌号码颁发制度很简单,按顺序,从0000到9999共10000个号码,他们车也不多,而且随时可能有报废的车车牌号也跟着废弃了。
现在已经知道办理了K个牌照,从0000开始的连续的K个,Mr.L很不爽,由于某些原因,他要M天后才能办理牌照,作为管理员,你已经知道了这M天的牌照预约情况,一共有P条预约信息,预约有2种:
- 今天有R个人预约办理牌照,那么会从0000开始找R个空位给与他们牌照;
2、今天某个牌照要报废,直接把这个位置置空就是了。
3、同一天内,总是先处理报废的事情,再处理新申请的事情。
Mr.L想知道M天后,他想要得牌照还在不在……
输入
第一行包含一个整数T,表示有T组数据
每组数据,第一行包含2个整数K和P,和题目描述一致,其中P<=50。
以下P行每行包含信息格式两种之一:
X N L 表示第X天有L个申请,N是标志字符
X D R 表示第X天有个编号为R的要报废,D是标志字符,保证数据合法。
保证输入数据中天数小的在前面出现,但不保证D一定在N前出现。
输出
处理完了P个预约后,返回4444这个号码还是不是空的,是输出“Yes”,否则输出“No”。
样例输入
2
0 3
5 N 1000
7 N 2000
7 D 1234
4000 3
2 N 446
4 N 1
4 D 4444
样例输出
Yes
No
思路:先把天数一样的按照 D先 N后 的顺序排个序,然后暴力模拟就行了,拿数组记录是否出现过车牌。如果是N 那么for循环遍历0到10000,找到L个位置变为1,如果是D,那么把当前位置的数组值改为0,最后查询a[4444]的值即可
代码:
#include<iostream> #include<algorithm> #include<cstdio> #include<cstring> #define LL long long using namespace std; struct note{ char cmd; int day,id; }p[100]; bool cmp(note x,note y){ if(x.day != y.day) return x.day < y.day; return x.cmd < y.cmd; } int main() { int k,t,n; for(scanf("%d",&t);t--;){ scanf("%d %d",&k,&n); int a[10001]={}; for(int i = 0 ; i < k ; i++) a[i] = 1; //初始K天已经被用掉了 for(int i = 0 ; i < n ; i++){ scanf("%d %c %d",&p[i].day,&p[i].cmd,&p[i].id); } sort(p,p+n,cmp); //根据 D先 N后的顺序排序 for(int i = 0 ; i < n ; i++){ if(p[i].cmd == 'N'){ for(int j = 0 ; j <= 10000&& p[i].id != 0 ;j++){ if(a[j] == 0){ a[j] = 1; p[i].id-=1; } }//暴力更新 } if(p[i].cmd == 'D'){ a[p[i].id] = 0; } } (!a[4444])?puts("Yes"):puts("No"); } }