Codeforces Round #345 D. Image Preview(二分)
题意:看一个图片需要1单位时间,如果是 w 需要翻转 b 时间,切换到相邻位置(往左或者往右)需要 a 时间,求T时间最多能看几张图片
从第一个开始向右走看若干个图片然后往如果往左走就不会再往右走了,也就是只能一次改变方向,多次改变方向就得不偿失了,浪费时间。所以一次枚举能看图片的数量n,往右能看1到n个,那么往左就有 (n - 往右的)个,然后算出时间跟T相比
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 using namespace std; 5 const int Max = 5e5 + 10; 6 typedef long long LL; 7 int pri[Max]; 8 char num[Max]; 9 int n, a, b, T; 10 bool check(int mid) 11 { 12 for (int i = 1; i <= mid; i++) 13 { 14 LL sum1 = pri[i] + pri[n] - pri[n - (mid - i)]; // 往右 往左 到达的位置 的 翻转和阅读总时间, 15 LL sum2 = min((i - 1) * a * 2 + (mid - i) * a, (i - 1) * a + (mid - i) * a * 2); // 可以从 左边 切换到右边,也可以从右边切换到左边 16 if (sum1 + sum2 <= (LL)T) 17 return true; 18 } 19 return false; 20 } 21 int main() 22 { 23 scanf("%d%d%d%d", &n, &a, &b, &T); 24 getchar(); 25 scanf("%s", num + 1); 26 for (int i = 1; i <= n; i++) 27 pri[i] = pri[i - 1] + 1 + (num[i] == 'w' ? b : 0); //pri【i】存的是从第一张切换到看第 i 张图片所需要的时间,包括旋转和阅读 28 int l = 0, r = n; 29 while (l < r) 30 { 31 int mid = (l + r + 1) / 2; // 不加一会死循环, r = l + 1时, 32 if (check(mid)) 33 l = mid; 34 else 35 r = mid - 1; 36 } 37 printf("%d\n", l); 38 return 0; 39 }