Codeforces 650B Image Preview(尺取法)
题目大概说手机有n张照片。通过左滑或者右滑循环切换照片,滑动需要花费a时间;看一张照片要1时间,而看过的可以马上跳过不用花时间,没看过的不能跳过;有些照片要横着看,要花b时间旋转方向。那么问T时间下最多可以看多少张相片。
先确定左滑最多能看到哪张,然后用另一个指针从第一张照片往右移动,这代表先右滑然后左滑的方式看照片,而每次向右的指针移动计算其时间,不合法的话就通过向左的指针向右移修正时间;
而先左滑然后右滑的方式同理。
模拟题,好难写。。不过写好后提交居然就1A了。。
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 char str[1111111]; 6 bool vis[1111111]; 7 int main(){ 8 int n,a,b,T; 9 scanf("%d%d%d%d",&n,&a,&b,&T); 10 scanf("%s",str); 11 12 int i=0,j=0,ans=0; 13 int t=T,cnt=0; 14 while(j<n){ 15 if(str[j]=='w') t-=b; 16 --t; 17 if(t<0) break; 18 ++cnt; 19 t-=a; 20 ++j; 21 } 22 if(cnt==0){ 23 putchar('0'); 24 return 0; 25 } 26 ans=max(ans,cnt); 27 t=T; 28 for(int k=0; k<cnt; ++k){ 29 if(str[k]=='w') t-=b; 30 --t; 31 if(k!=cnt-1) t-=a; 32 vis[k]=1; 33 } 34 j=cnt-1; 35 while(true){ 36 if(--i==-1) i=n-1; 37 if(vis[i]) break; 38 t-=a; 39 if(str[i]=='w') t-=b; 40 --t; 41 t-=a; 42 while(t<0 && j>0 && vis[j]){ 43 t+=a; 44 if(str[j]=='w') t+=b; 45 ++t; 46 --cnt; 47 vis[j]=0; 48 --j; 49 } 50 if(t<0) break; 51 ++cnt; 52 ans=max(ans,cnt); 53 } 54 55 memset(vis,0,sizeof(vis)); 56 i=0; j=0; 57 t=T; cnt=0; 58 while(cnt<n){ 59 if(str[i]=='w') t-=b; 60 --t; 61 if(t<0) break; 62 ++cnt; 63 t-=a; 64 if(--i==-1) i=n-1; 65 } 66 67 ans=max(ans,cnt); 68 t=T; 69 for(int k=0,tmp=0; k<cnt; ++k){ 70 if(str[tmp]=='w') t-=b; 71 --t; 72 if(k!=cnt-1) t-=a; 73 vis[tmp]=1; 74 if(--tmp==-1) tmp=n-1; 75 } 76 if(++i==n) i=0; 77 while(true){ 78 if(++j==n) j=0; 79 if(vis[j]) break; 80 t-=a; 81 if(str[j]=='w') t-=b; 82 --t; 83 t-=a; 84 while(t<0 && i && vis[i]){ 85 t+=a; 86 if(str[i]=='w') t+=b; 87 ++t; 88 --cnt; 89 vis[i]=0; 90 if(++i==n) i=0; 91 } 92 if(t<0) break; 93 ++cnt; 94 ans=max(ans,cnt); 95 } 96 97 printf("%d",ans); 98 return 0; 99 }