[noip2016d2t2]蚯蚓
·碰到这种题,一定要好好打暴力
题面比较长,但只要细心看下去就可以找到突破口
直接模拟或者写堆都可以拿到部分分
http://www.cnblogs.com/ljh2000-jump/p/6184271.html
正解的关键在于看出结论:把每次切掉的蚯蚓产生的两部分长度分别存入队尾,两个队列单调不上升
于是开三个队列,每次判断队头即可
还有比较麻烦的一点在于长度随时间的增加,用了一些小技巧去计算
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<cmath> 5 using namespace std; 6 const int inf=2147483647; 7 const int maxn=7100500;//数组长度<=n+m 8 int u,v,n,m,q,time; 9 struct data{ 10 int num,t; 11 }L[4][maxn]; 12 int h[5],e[5]; 13 bool cmp(data x,data y){ 14 return x.num>y.num; 15 } 16 int read(){ 17 int x=0,f=1; 18 char ch=getchar(); 19 while (ch<'0'||ch>'9'){ 20 if (ch=='-') f=-1; 21 ch=getchar(); 22 } 23 while (ch>='0'&&ch<='9'){ 24 x=x*10+ch-'0'; 25 ch=getchar(); 26 } 27 return x*f; 28 } 29 int get(int i,int x){//第i个队列队首在时间x的长度 30 if (h[i]>e[i]) return -inf; 31 return L[i][h[i]].num+q*(x-L[i][h[i]].t-1); 32 } 33 int compare(int x){//时间x,对比三个队头 34 int pos=1; 35 for (int i=1;i<=3;i++){ 36 if(h[i]<=e[i]) 37 if (get(i,x)>get(pos,x)) pos=i; 38 } 39 return pos; 40 } 41 int main(){ 42 n=read(),m=read(),q=read(); 43 u=read(),v=read(),time=read(); 44 memset(L,0,sizeof(L)); 45 for (int i=1;i<=n;i++) 46 L[1][i].num=read(); 47 sort(L[1]+1,L[1]+1+n,cmp); 48 h[1]=h[2]=h[3]=1; 49 e[1]=n;e[2]=e[3]=0; 50 for (int i=1;i<=m;i++){ 51 int pos=compare(i),len=get(pos,i); 52 if (i%time==0) { 53 if (i==time) printf("%d",len); 54 else printf(" %d",len); 55 } 56 h[pos]++; 57 L[2][++e[2]].num=int(u*1.0/v*len); 58 L[3][++e[3]].num=len-int(u*1.0/v*len); 59 L[2][e[2]].t=i; 60 L[3][e[3]].t=i; 61 } 62 printf("\n"); 63 for (int i=1;i<=n+m;i++){ 64 int pos=compare(m+1),len=get(pos,m+1); 65 if (i%time==0) { 66 if (i==time) printf("%d",len); 67 else printf(" %d",len); 68 } 69 h[pos]++; 70 } 71 return 0; 72 }
==暴力真的很重要!!