题目大意:就是环形的路上,路上有n个加油站,每个加油站可以加一定量的油pi,到达下一个加油站需要消耗qi升油,现在问可以从出发点驶出然后能够到达起点的出发点序号最小是多少,如果不可能输出不可能。
关键点:
1.从最小的出发点t出发,如果最终回到了起始点当然这时就可以直接输出了,如果到达某个点k,从k不能到达下一个加油站,那么最小的出发点一定是要大于k的,证明的关键点是在 t~k中的任意一点,从t点出发到达不了k+1,那么t+1中的任意一点也不可能到达k,因为对于任何一点j,从t出发到达j的剩余油量一定大于等于0.
然后就是 记录一下出发点能够达到的最大点,,达到最大点剩余的油量。。。
//
// main.cpp
// uva 11093 - Just Finish it up
//
// Created by XD on 15/8/14.
// Copyright (c) 2015年 XD. All rights reserved.
//
#include <iostream>
#include <string>
#include <queue>
#include <stack>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include<vector>
#include <string.h>
#include <string>
#include <algorithm>
#include <set>
#include <map>
#include <cstdio>
using namespace std ;
const int maxn =100001 ;
int p[maxn] ;
int q[maxn] ;
int vis[maxn] ;
int tnext[maxn] ;
int remain_gas[maxn] ;
int start ,n ;int flag ;
enum{FINISH=-2,RESTART=-1} ;
int running(int s)
{
vis[s] = 1 ;
int gas = 0 ;flag = 0 ;
while (gas + p[s] >=q[s] && (flag == 0||s != start )) {
gas = gas + p[s] - q[s] ;
vis[s] =1 ;
s = (s+1) % n ;
flag = 1 ;
if (tnext[s]!= -1) {
gas += remain_gas[s] ;
s = tnext[s] ;
// s=(s+1)%n ;
}
}
if (s == start && flag == 1) {
return FINISH ;
}
else{
remain_gas[start] = gas ;
return (s+1)%n;
}
}
int main() {
int T ; scanf("%d" ,&T) ;
int casenum = 0;
while (T--) {
memset(vis, 0,sizeof(vis)) ;
scanf("%d" ,&n) ;
fill(tnext, tnext + n + 1, -1) ;
for (int i = 0; i < n ; i++) {
scanf("%d" ,&p[i]) ;
}
for (int i = 0; i < n ; i++) {
scanf("%d" ,&q[i]) ;
}
start = 0 ;int tstart = 0 ;
while (!vis[start]) {
start = running(start) ;
if (start == FINISH) {
printf("Case %d: Possible from station %d\n",++casenum ,tstart +1) ;
break ;
}
else{
if(flag==1) tnext[tstart] = start == 0?n-1:start-1;
tstart = start ;
}
}
if (start != FINISH) {
printf("Case %d: Not possible\n",++casenum) ;
}
}
return 0;
}