题目描述:

洛谷P2827 NOIP2016 蚯蚓

 

输入 

洛谷P2827 NOIP2016 蚯蚓

 

 

输出 

洛谷P2827 NOIP2016 蚯蚓

 

 洛谷P2827 NOIP2016 蚯蚓

 

思路分析——70分写法:

  看到每次取出最大值,第一眼想到的就是优先队列,我们可以每一次取完队首元素后将其分开后两段的长度进行计算,再放入队列之中即可但题目中要求,除被切开的蚯蚓外,其余蚯蚓长度要变长,每次把队中元素取出并加上q再放入队中?不用说我们也知道这是不行的,那我们可以考虑定义一个tap来表示当前队内蚯蚓的长度增加的总的长度,每次从队首取出元素,给它加上tap,使它变为它应该的此时的长度,在计算为两段之后将每一段的长度再减去tap的基础上再减一个q(因为其他数都加上了q,相当于队外的元素减q),tap+=q,之后以此类推;之后按照要求输出对应排名的蚯蚓长度即可。

附上代码:

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<queue>
 5 using namespace std;
 6 const int N=1e7+10;
 7 struct Qiuyin{
 8     long long length;
 9     Qiuyin(int a){
10         length=a;
11     }
12     bool operator < (const Qiuyin& a)const{  //重载运算符,方便用优先队列 
13         return a.length>length;
14     }
15 };
16 int n,m,q,u,v,t;
17 priority_queue<Qiuyin>p;
18 int main(){
19     scanf("%d%d%d%d%d%d",&n,&m,&q,&u,&v,&t);
20     for(int i=1;i<=n;++i){
21         int x;
22         scanf("%d",&x);
23         p.push(Qiuyin(x));
24     }
25     double cnt=(double)u/(double)v;
26     int cnt1=t,cnt2=t;  //cnt1,2分别用于记录当前操作到何值时需要输出 
27     long long tap=0;
28     for(int i=1;i<=m;++i){
29         if(i==cnt1){
30             printf("%lld ",p.top().length+tap);
31             cnt1+=t;
32         }
33         int t=p.top().length+tap; p.pop(); //复原队首元素 
34         tap+=q;  //更新tap 
35         int a=(double)t*cnt;
36         p.push(Qiuyin(a-tap));p.push(Qiuyin(t-a-tap)); //加入队中时要减tap 
37     }
38     printf("\n");
39     for(int i=1;i<=m+n;++i){
40         if(i==cnt2){  //以此输出规定排名长度 
41             printf("%lld ",p.top().length+tap);
42             cnt2+=t;
43         }
44         p.pop();
45     }
46     return 0;
47 }
View Code

相关文章: