NowCoder小杰的签到题(模拟,思维)
链接:
https://www.nowcoder.com/acm/contest/52/M
题意:
给定n个队伍的到场时间, 有3个报道位, 每个队伍报道需要b时间, 求所有报道完成的时间。
分析:
一开始写了一个模拟时间轴的, 虽然过了,但是在时间很大的时候行不通。
1 #include<bits/stdc++.h> 2 using namespace std; 3 int main() 4 { 5 int a[3], u[3]; 6 int n, b, time, ok, T; 7 scanf("%d", &T); 8 while(T--){ 9 time = 0, ok = 0; 10 a[0] = a[1] = a[2] = 0; 11 u[0] = u[1] = u[2] = 0; 12 priority_queue<int, vector<int>, greater<int> > q; 13 scanf("%d", &n); 14 for(int i = 0; i < n; i++){ 15 int t; scanf("%d", &t); 16 q.push(t); 17 } 18 scanf("%d", &b); 19 a[0] = q.top() + b; q.pop(); 20 u[0] = 1; 21 while(1){ 22 23 for(int i = 0; i < 3; i++){ 24 if(u[i] && time >= a[i]) u[i] = 0; 25 if(!q.empty() && time >= q.top() && !u[i]){ 26 u[i] = 1; 27 a[i] = time + b; 28 q.pop(); 29 } 30 } 31 // printf("%d %d %d %d\n", time, a[0], a[1], a[2]); 32 if(u[0] == 0 && u[1] == 0 && u[2] == 0 && q.empty()) break; 33 time++; 34 } 35 printf("%d\n", time); 36 } 37 return 0; 38 }
后来看了一下人家的代码, 发现可以用优先队列模拟报道。
就是一开始对报道时间排序,将3个报道位置加入优先队列, 然后每次都取最早完成报道的时间, 如果这个时间t小于队伍时间, 那么就将a[i] + b入队, 否则将t+b入队。
最后就能求出全部完成报道的时间了
1 #include<bits/stdc++.h> 2 using namespace std; 3 int main() 4 { 5 // freopen("debug.txt","r", stdin); 6 int a[1234]; 7 int n, b, T; 8 scanf("%d", &T); 9 while(T--){ 10 scanf("%d", &n); 11 for(int i = 0; i < n; i++){ 12 scanf("%d", &a[i]); 13 } 14 scanf("%d", &b); 15 sort(a, a + n); 16 if( n <= 3 ){ 17 printf("%d\n", a[n-1] + b); 18 continue; 19 } 20 priority_queue<int, vector<int>, greater<int> > q; 21 for(int i = 0; i < 3; i++) q.push(a[i] + b); 22 for(int i = 3; i < n; i++){ 23 int x = q.top();q.pop(); 24 if(a[i] < x){ 25 q.push(x + b); 26 } 27 else q.push(a[i] + b); 28 } 29 while(!q.empty()){ 30 q.pop(); 31 if(q.size() == 1) printf("%d\n", q.top()); 32 } 33 } 34 return 0; 35 }