题目
源地址:
http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2034
理解
比赛的时候没有敲出来。
当时看范神拿了一血,默默地去看题。然后觉得应该跟小白书上那个加油站的优先队列是一样的题目,敲了一会儿之后感觉不对,然后就放弃了这道题。后来想想,这两道题的区别在于,一个是环形的路线,一个是单向的路径,处理的方法应该是不一致的。比赛过后想到,其实就算是环形,也是可以处理成单向问题的。只要开一个两倍MAXN的数组,然后从起点开始截取n个数,就能将一个环从起点处截成一条直线。然后就能用类似的办法进行处理了。
具体的实现过程是这样:只要用一个数组保存可以添加的油量,然后不断减去消耗的油量,然后再不断进行求和。很显然,当a[i]>=start
时,这个站点时可以通过的;当a[i]<start
时,这个站点是不可通过的。然后再遍历寻找字典序最小的起点。
代码
#define MAXN 100000+10
int a[2*MAXN],x;
int n,t,flag=0;
int main(int argc, char const *argv[])
{
scanf("%d", &t);
while(t--)
{
flag++;
scanf("%d", &n);
for(int i=1;i<=n;i++)
{
scanf("%d", &a[i]);
a[n+i]=a[i];
}
for(int i=1;i<=n;i++)
{
scanf("%d", &x);
a[i]-=x;
a[n+i]-=x;
}
a[0]=0;
for(int i=1;i<=2*n;i++)
{
a[i]+=a[i-1];
}
int s=0,mi=1,cn=0;
for(int i=0;i<=2*n;i++)
{
if(a[i]>=mi)
{
if(++cn>n) break;
}
else
{
mi=a[i];
s=i;
cn=1;
if(i>=n) break;
}
}
printf("Case %d: ", flag);
if(cn>n) printf("Possible from station %d\n", s+1);
else printf("Not possible\n");
}
return 0;
}
更新日志
- 2014年11月6日 已AC。