CCF 201709-2 公共钥匙盒
题意:有一个学校的老师共用N个教室,按照规定,所有的钥匙都必须放在公共钥匙盒里,老师不能带钥匙回家。每次老师上课前,都从公共钥匙盒里找到自己上课的教室的钥匙去开门,上完课后,再将钥匙放回到钥匙盒中。钥匙盒一共有N个挂钩,从左到右排成一排,用来挂N个教室的钥匙。一串钥匙没有固定的悬挂位置,但钥匙上有标识,所以老师们不会弄混钥匙。每次取钥匙的时候,老师们都会找到自己所需要的钥匙将其取走,而不会移动其他钥匙。每次还钥匙的时候,还钥匙的老师会找到最左边的空的挂钩,将钥匙挂在这个挂钩上。如果有多位老师还钥匙,则他们按钥匙编号从小到大的顺序还。如果同一时刻既有老师还钥匙又有老师取钥匙,则老师们会先将钥匙全还回去再取出。今天开始的时候钥匙是按编号从小到大的顺序放在钥匙盒里的。有K位老师要上课,给出每位老师所需要的钥匙、开始上课的时间和上课的时长,假设下课时间就是还钥匙时间,请问最终钥匙盒里面钥匙的顺序是怎样的?
分析:
1、记录每一时刻还的钥匙编号和取走的钥匙编号。
2、记录每个位置的钥匙编号和每个钥匙所在位置。
3、枚举时间,按题意操作即可。
#include<cstdio> #include<cstring> #include<cstdlib> #include<cctype> #include<cmath> #include<iostream> #include<sstream> #include<iterator> #include<algorithm> #include<string> #include<vector> #include<set> #include<map> #include<stack> #include<deque> #include<queue> #include<list> #define lowbit(x) (x & (-x)) const double eps = 1e-8; inline int dcmp(double a, double b){ if(fabs(a - b) < eps) return 0; return a > b ? 1 : -1; } typedef long long LL; typedef unsigned long long ULL; const int INT_INF = 0x3f3f3f3f; const int INT_M_INF = 0x7f7f7f7f; const LL LL_INF = 0x3f3f3f3f3f3f3f3f; const LL LL_M_INF = 0x7f7f7f7f7f7f7f7f; const int dr[] = {0, 0, -1, 1, -1, -1, 1, 1}; const int dc[] = {-1, 1, 0, 0, -1, 1, -1, 1}; const int MOD = 1e9 + 7; const double pi = acos(-1.0); const int MAXN = 10000 + 110; const int MAXT = 1000 + 10; using namespace std; set<int> st[MAXN];//时刻i取走的钥匙编号 set<int> et[MAXN];//时刻i放回的钥匙编号 int vis1[MAXT];//第i个位置存放的钥匙编号 int vis2[MAXT];//编号为i的钥匙所在位置 int main(){ int N, K; scanf("%d%d", &N, &K); for(int i = 1; i <= N; ++i){ vis1[i] = i; vis2[i] = i; } int w, s, c, e; int tot = 0; while(K--){ scanf("%d%d%d", &w, &s, &c); e = s + c; st[s].insert(w); et[e].insert(w); tot = max(tot, e); } for(int i = 1; i <= tot; ++i){ int j = 1; for(set<int>::iterator it = et[i].begin(); it != et[i].end(); ++it){ for(; j <= N; ++j){ if(!vis1[j]){ vis1[j] = *it; vis2[*it] = j; ++j; break; } } } for(set<int>::iterator it = st[i].begin(); it != st[i].end(); ++it){ vis1[vis2[*it]] = 0; } } for(int i = 1; i <= N; ++i){ if(i != 1) printf(" "); printf("%d", vis1[i]); } printf("\n"); return 0; }