[NOIP2016] 蚯蚓

来源:互联网 发布:牛顿环实验数据 编辑:程序博客网 时间:2024/04/29 10:55

题目描述

这里写图片描述


输入格式

这里写图片描述


输出格式

输出到文件 earthworm.out
第一行输出[m/t]个整数,按时间顺序,依次输出第t秒,第2t秒,第3t秒……被切断蚯蚓(在被切断前)的长度。
这里写图片描述


样例数据

样例输入

输入样例#1:
3 7 1 1 3 1
3 3 2
输入样例#2:
3 7 1 1 3 2
3 3 2
输入样例#3:
3 7 1 1 3 9
3 3 2

样例输出

输出样例#1:
3 4 4 4 5 5 6
6 6 6 5 5 4 4 3 2 2
输出样例#2:
4 4 5
6 5 4 3 2
输出样例#3:
//空行
2


说明

【样例解释1】
在神刀手到来前:3只蚯蚓的长度为3,3,2。
1秒后:一只长度为3的蚯蚓被切成了两只长度分别为1和2的蚯蚓,其余蚯蚓的长度增加了1。最终4只蚯蚓的长度分别为(1,2),4,3。括号表示这个位置刚刚有一只蚯蚓被切断
2秒后:一只长度为4的蚯蚓被切成了1和3。5只蚯蚓的长度分别为:2,3,(1,3),4。
3秒后:一只长度为4的蚯蚓被切断。6只蚯蚓的长度分别为:3,4,2,4,(1,3)。
4秒后:一只长度为4的蚯蚓被切断。7只蚯蚓的长度分别为:4,(1,3),3,5,2,4。
5秒后:一只长度为5的蚯蚓被切断。8只蚯蚓的长度分别为:5,2,4,4,(1,4),3,5。
6秒后:一只长度为5的蚯蚓被切断。9只蚯蚓的长度分别为:(1,4),3,5,5,2,5,4,6。
7秒后:一只长度为6的蚯蚓被切断。10只蚯蚓的长度分别为:2,5,4,6,6,3,6,5,(2,4)。所以,7秒内被切断的蚯蚓的长度依次为3,4,4,4,5,5,6。7秒后,所有蚯蚓长度从大到小排序为6,6,6,5,5,4,4,3,2,2

【样例解释2】
这个数据中只有t=2与上个数据不同。只需在每行都改为每两个数输出一个数即可。
虽然第一行最后有一个6没有被输出,但是第二行仍然要重新从第二个数再开始输出。
【样例解释3】
这个数据中只有t=9与上个数据不同。
注意第一行没有数要输出,但也要输出一个空行。
这里写图片描述


题目分析

正常想法:堆+偏移(这个写起来比正解还麻烦。。。)
预计分数:80分
正解:
开三个队列,第一个队列储存没有被切得蚯蚓,第二个队列储存被切过得前一半蚯蚓,第三个队列储存被切过的后一半蚯蚓。
事先将第一个队列从大到小排序,便可以保证所有队列均有序(想一想,为什么?)
每次从三个队列中取出一个最大的切掉,同时将偏移量delta加着走,当然要保证队列里的元素是减了delta的。
为什么需要引入偏移量delta呢?因为我们要保持队列有序,如果手动排序就nlogn了,就成了暴力,因此需要delta来间接维护队列。
注意要开long long!


源代码

#include<algorithm>#include<iostream>#include<iomanip>#include<cstring>#include<cstdlib>#include<vector>#include<cstdio>#include<cmath>#include<queue>using namespace std;inline const int Get_Int() {    int num=0,bj=1;    char x=getchar();    while(x<'0'||x>'9') {        if(x=='-')bj=-1;        x=getchar();    }    while(x>='0'&&x<='9') {        num=num*10+x-'0';        x=getchar();    }    return num*bj;}bool cmp(long long a,long long b) {    return a>b;}int n,m,q,u,v,t,cnt=0;long long a[8000005],Delta=0;deque<long long>Q[4];int main() {    n=Get_Int();    m=Get_Int();    q=Get_Int();    u=Get_Int();    v=Get_Int();    t=Get_Int();    for(int i=1; i<=n; i++)a[i]=Get_Int();    sort(a+1,a+n+1,cmp);    for(int i=1; i<=n; i++)Q[1].push_back(a[i]);    for(int i=1; i<=m; i++) {        long long Max=-1e10,maxl;        for(int j=1; j<=3; j++)            if(!Q[j].empty()&&Q[j].front()>Max) {                Max=Q[j].front();                maxl=j;            }        Q[maxl].pop_front();        Max+=Delta;        if(i%t==0)printf("%lld ",Max);        Delta+=q;        long long Left=Max*u/v,Right=Max-Left;        Q[2].push_back(Left-Delta);        Q[3].push_back(Right-Delta);    }    putchar('\n');    while(!Q[1].empty()||!Q[2].empty()||!Q[3].empty()) {        cnt++;        long long Max=-1e10,maxl;        for(int i=1; i<=3; i++)            if(!Q[i].empty()&&Q[i].front()>Max) {                Max=Q[i].front();                maxl=i;            }        Max+=Delta;        if(cnt%t==0)printf("%lld ",Max);        Q[maxl].pop_front();    }    return 0;}

0 0
原创粉丝点击