题目
有N个加油站构成一个环形,每个加油站可以加ai的油,从第i个加油站走到第i+1个需要消耗bi的油。问按照顺序从哪个加油站开始可以走一圈回到出发点。初始没有油。
分析
贪心。计算出每个点的净值:c[i] = p[i] - q[i]。有点像最大子段和,保存当前区间的起始点和走到当前位置的油的余量。如果余量为负数,就重新开始找起始点。
粗略证明:设i < j,如果sum{c[i],…,c[j]} < 0,显然i不是解;否则,sum{c[i],…,c[j]} ≥ 0,则如果j是解,i也是解,算法会输出i而不是j;因此,算法正确。
说明
ε=(´ο`*)))唉
#include <stdio.h>
#include <stdlib.h>
int a[100002];
int b[100002];
int c[200005];
int main()
{
int T, N;
while (~scanf("%d", &T))
for (int t = 1; t <= T; ++ t) {
scanf("%d", &N);
for (int i = 1; i <= N; ++ i) {
scanf("%d", &a[i]);
}
for (int i = 1; i <= N; ++ i) {
scanf("%d", &b[i]);
}
int sum = 0;
for (int i = 1; i <= N; ++ i) {
c[i] = c[i+N] = a[i] - b[i];
sum += c[i];
}
int now = 0, space = 1;
for (int i = 1; i <= 2*N; ++ i) {
now += c[i];
if (now < 0) {
now = 0;
space = i+1;
}
if (i-space+1 > N) {
break;
}
}
printf("Case %d: ", t);
if (sum < 0 || space > N) {
printf("Not possible\n");
} else {
printf("Possible from station %d\n", space);
}
}
return 0;
}