题目链接:Codeforces Round #6 Div.2
题目大意:Alice和Bob吃巧克力棒,给出一堆巧克力棒,长度不一,吃巧克力棒的速度是相同且均匀的。Alice从左边的巧克力棒开始吃,Bob同时从右边吃。如果两人同时看到最后一根巧克力棒,Bob会让给Alice吃。吃完为止。输出两人吃的巧克力棒个数。
思路:既然速度是均匀的,那么可以根据巧克力棒长度之和的一半key来判定两人吃的个数。保存巧克力棒的前缀和,在前缀和当中找到这个key,如果找不到,就找到它的邻居。关键就在于“争议”巧克力棒的判定。(当两人同时看到最后一根巧克力棒……)
我们可以找到小于或等于key的前缀和,作为Alice的总量(肯定属于Alice),然后中间留下一根棒,后面的和最为Bob的总量,单独处理中间这根争议棒。
当时做不对这道题……因为——1.二分姿势不标准 2.判定写不对(对前缀和的理解)。
使用二分的时候,如果对边界不会判定,可以使用一个ret来“记路”。
代码如下:
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
int sum[100010];
int main() {
int n, a, key;
scanf("%d", &n);
sum[0] = 0;
for(int i = 1; i <= n; i++) {
scanf("%d", &a);
sum[i] = sum[i-1] + a;
}
key = sum[n] / 2;
int l = 1, r = n, ans = 0;
while(l != r) {
int m = (l+r) >> 1;
if(sum[m] <= key) {
ans = m;
l = m + 1;
}//明显sum[ans]是不大于key的
else
r = m;
}//用ans来“记路”
if(sum[ans] <= sum[n] - sum[ans+1])
ans++;//对争议棒进行判定,相等或者Alice的少,这根就要给Alice
printf("%d %d\n", ans, n - ans);
return 0;
}