原文链接:UVA11093
题目大意:
环形跑到上有n个加油站,每个加油站可以加p[i]的油,而到下一个加油站需要q[i]的油,油箱无上限,求出能不能从某个加油站除法能可以走完一圈。
解题思路:
紫书上给的思路:如果从第0个加油站出发,无法到达p+1站,在第p个加油站终止,则0~p之间的所有加油站都可以。
原理很简单:既然可以从0到第p站说明,从0站到第1站(这里假设p不为0)的时候油箱里的有油只可能增多或者不变,不可能是负的(如果是负的不可能到第1站),所以理论上从第0站开始比从第1站更容易到达p+1,但是并没有到第p站。所以下次在开始可直接从第p+1站开始。时间复杂度O(n)。
代码:
#include<iostream>
#include<cstring>
using namespace std;
const int MAXN = 100001 + 5;
int main()
{
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
int T, n, kase = 0;
cin >> T;
while (T--) {
int p[MAXN], q[MAXN];
int gas = 0,begin = 0, pass = 0;//gas:the gas in the tank ; begin:the index of begin ;pass : the step had pass
bool head = true; //if is the first step in this round
cin >> n; //input
for (int i = 0; i < n; i++) cin >> p[i];
for (int i = 0; i < n; i++) cin >> q[i];
while (begin < n) {
int cur = pass % n; //the index of the station we staying
if (!head && begin == cur) break; //complate,and break
gas += p[cur] - q[cur]; //compute the gas left when go to the next station
if (gas >= 0) { //gas is enough
pass++; head = false;
}
else {
gas = 0;
begin = ++pass;
head = true;
}
}
if (begin >= n) cout << "Case " << ++kase << ": Not possible\n";
else cout << "Case " << ++kase << ": Possible from station " << begin + 1 << endl;
}
return 0;
}