Time Limit: 1000 MS Memory Limit: 32768 KB Description 学生会里只有一台打印机,但是有很多文件需要打印,因此打印任务不可避免地需要等待。有些打印任务比较急,有些不那么急,所以每个任务都有一个1~9间的优先级,优先级越高表示任务越急。
打印机的运作方式如下:首先从打印队列里取出一个任务J,如果队列里有比J更急的任务,则直接把J放到打印队列尾部,否则打印任务J(此时不会把它放回打印队列)。 输入打印队列中各个任务的优先级以及所关注的任务在队列中的位置(队首位置为0),输出该任务完成的时刻。所有任务都需要1分钟打印。例如,打印队列为{1,1,9,1,1,1},目前处于队首的任务最终完成时刻为5。
Translated by @HuangBo
Input 输入T 接下来T组数据 每组数据输入N,KEY。接下来N个数,KEY代表目标任务
T <= 100 N <= 100 KEY < N Output 输出每组任务完成的时刻 Sample Input 3 1 0 5 4 2 1 2 3 4 6 0 1 1 9 1 1 1 Sample Output 1 2 5 Source UVA12100 Translated by @HuangBo
基本思路就是用queue模拟打印队列,用key模拟我们想知道的那个数据的位置,每当有一个元素出队或移动时,key的值都会进行相应的改变以模拟操作完后元素的位置,中间还有一个操作是动态改变最大值,由于每次打印的元素都是目前队列中的最大值,并且打印完后剩下队列的最大值是上一个队列中第二大的值,明白这一点之后,就可以用一个倒序数组装所有数据,每次最大值改变的时候让数组下标加1即可,下面是ac代码:
#include<iostream> #include<queue> #include<algorithm> #include<vector> using namespace std; bool cmp(int x,int y) { return x>y; //定义sort函数的排序规则 } int main() { queue<int> q; //创建一个队列 int c[105]; //用来动态改变最大值 int a,t,n,key,time=0,max,k=1; cin>>t; //接下来会有t组数据 for(int i=1;i<=t;++i) { cin>>n>>key; for(int j=1;j<=n;++j) { cin>>a; q.push(a); c[j]=a; } //让所有元素入队 ,把所有元素装到c中备用 //if(n==1) max=c[1]; //else //{ sort(c+1,c+n+1,cmp); //对c数组排序 max=c[k++]; //max的初值是所有元素的最大值 //} //cout<<key; //cout<<q.front()<<" "<<c[1]; while(true) { //cout<<key; //printf("key1 = %d\n", key); if(q.front()>=max) //如果即将打印的元素优先级大于等于优先级最大的元素 { //printf("key3 = %d\n", key); //cout<<key; //if(k1!=key) k1--; q.pop(); //弹出它 max=c[k++]; //改变max的值 time++; //操作次数加一 //cout<<max<<" "<<key<<endl; if(key==0) break; //循环退出条件是弹出目标元素 else key--; //弹出了一个元素,就相当于目标元素前移了1 } else //如果即将打印的匀速优先级小于优先级最大的元素 { //printf("key2 = %d\n", key); q.push(q.front()); q.pop(); //那就把它弄到队列最后去 if(key==0) { key+=q.size()-1; //如果这个是目标元素,则加上相应的值模拟它的移动 } else { key--; //如果它不是目标元素,就相当于目标元素前移了1 } } //cout<<max<<" "<<key<<endl; } cout<<time<<endl; //输出操作次数 while(true) { if(!q.empty()) q.pop(); else break; //清空队列 } time=0; //重置操作次数(很重要别忘了) k=1; //重置c数组的下标 } return 0; }