zoukankan      html  css  js  c++  java
  • 【uva 11093】Just Finish it up(算法效率--贪心)

    题意:环形跑道上有N个加油站,编号为1~N。第 i 个加油站可以加油Ai加仑,从加油站 i 开到下一站需要Bi加仑汽油。问可作为起点走完一圈后回到起点的最小加油站编号。

    解法:我们把每个加油站的Ai,Bi合并,把Ai-Bi看成N个点的权Ci,表示经过 i 的剩余油量。可知可通过第 i 个加油站就是sum{}+Ci>=0,sum{}表示从起点开到 i 之前剩余的油量,sum{}>=0。因此,若sum{}+Ci<0,那么从这时枚举的起点到 i 之间的所有点都不能作为起点,因为这时的sum{}已经是以他们为起点所能达到的最大值了,不可能有更多的油量剩余,一定不能通过点 i。便枚举 i+1 为起点,继续判断。

    P.S.由于是环,判断走完一圈也有点麻烦,大家要小心。我觉得我打的虽然比较短,但也不是很优美。= =

     1 #include<cstdio>
     2 #include<cstdlib>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<iostream>
     6 #include<queue>
     7 using namespace std;
     8 const int N=100010;
     9 
    10 int n;
    11 int a[N],b[N];
    12 int mmax(int x,int y) {return x>y?x:y;}
    13 int check(int x)
    14 {
    15     int h=0,t=x;
    16     bool tf=true;
    17     while(1)
    18     {
    19       if (t==x&&!tf) return -1;
    20       h+=a[t]-b[t];
    21       if (h<0) return t;
    22       tf=false;
    23       t=(t+1)%n;
    24     }
    25 }
    26 int main()
    27 {
    28     int T;
    29     scanf("%d",&T);
    30     for (int kase=1;kase<=T;kase++)
    31     {
    32       scanf("%d",&n);
    33       for (int i=0;i<n;i++) scanf("%d",&a[i]);
    34       for (int i=0;i<n;i++) scanf("%d",&b[i]);
    35       int ans=n,x=0,tmp,mx=-1;
    36       while (1)
    37       {
    38         if (x<=mx) break;
    39         tmp=check(x),mx=mmax(mx,x);
    40         if (tmp==-1) {ans=x;break;}
    41         else x=tmp+1;
    42       }
    43       if (ans!=n) printf("Case %d: Possible from station %d
    ",kase,ans+1);
    44       else printf("Case %d: Not possible
    ",kase);
    45     }
    46     return 0;
    47 }
  • 相关阅读:
    语言基础
    进制转换
    ado属性扩展
    ado数据模型和数据访问类,泛型集合
    完整的修改和删除
    完整的删除
    修改
    类库
    接口
    抽象类
  • 原文地址:https://www.cnblogs.com/konjak/p/6018851.html
Copyright © 2011-2022 走看看