zoukankan      html  css  js  c++  java
  • 8-13 Just Finish it up uva11093

    题意:环形跑道上有n n<=100000 个加油站  编号为1-n  第i个加油站可以加油pi加仑   从加油站i开到下一站需要qi加仑   你可以选择一个加油站作为起点 初始油箱为空   如果可以走完一圈  那么输出最小的起始站点  否则输出-1 

    如果   对每个加油站作为起始点进行枚举的话  那么复杂度为 n^2   

    其中有一个重要的思路可以优化:

    比如从第一个点最为起始点   如果能走一圈 那么就成了  第一个也为最小起始点

    如果 走到t点   t到t+1走不了     那么 第2个点到 第t个点作为起始点 都是一定不可行的!!

    接下来就将t+1作为起始点再次尝试遍历

    #include<bits/stdc++.h>
    using namespace std;
    #define N 100001
    
    int vis[N];
    int p[N],q[N];//p为加油  q为油耗
    int n;
    
    int go(int start)
    {
        int oil=p[start]-q[start];
        if(oil<0) return start;
        for(int i=(start+1)%n; i!=start;i=(i+1)%n )
        {
            oil+=p[i]-q[i];
            if(oil<0)return i;
        }
        return N;
    }
    
    int solve(void)
    {
        int start=0;
        memset(vis,0,sizeof vis);
        vis[0]=1;
        for(;;)
        {
            int e=go(start);
            if(e==N)return start;
            start=e+1;
            if(vis[start])return -1;
            vis[start]=1;
        }
    }
    
    int main()
    {
        int cas;cin>>cas;
        for(int kase=1;kase<=cas;kase++)
        {
          cin>>n;
          for(int i=0;i<n;i++)scanf("%d",&p[i]);
          for(int i=0;i<n;i++)scanf("%d",&q[i]);
    
          int ans=solve();
          printf("Case %d: ",kase);
          if(ans==-1)printf("Not possible
    ");
          else  printf("Possible from station %d
    ",ans+1);
        }
        return 0;
    }

    LRJ的代码更快更巧妙!去掉了vis数组

    // UVa11093 Just Finish it up
    // Rujia Liu
    #include<cstdio>
    
    const int maxn = 100000 + 5;
    int n, p[maxn], q[maxn];
    
    // returns s if success
    // otherwise, return the station you failed to reach
    // if you failed to reach the start, return -1
    int go(int s) {
      int fuel = p[s] - q[s];
      for(int i = (s+1)%n; i != s; i = (i+1)%n) {
        if(fuel < 0) return i;
        fuel += p[i] - q[i];
      }
      if(fuel < 0) return -1; // this means sum(p) < sum(q), so this case is impossible
      return s; // success
    }
    
    int solve() {
      int start = 0;
      for(;;) {
        int finish = go(start);
        if(finish < start) return -1; // wrapped around, or go(start) returns -1
        if(finish == start) return start;
        start = finish;
      }
    }
    
    int main() {
      int T;
      scanf("%d", &T);
      for(int kase = 1; kase <= T; kase++) {
        scanf("%d", &n);
        for(int i = 0; i < n; i++) scanf("%d", &p[i]);
        for(int i = 0; i < n; i++) scanf("%d", &q[i]);
        int ans = solve();
        printf("Case %d: ", kase);
        if(ans < 0) printf("Not possible
    ");
        else printf("Possible from station %d
    ", ans+1);
      }
      return 0;
    }
  • 相关阅读:
    4. Qt的容器类
    hdu 4507 数位dp(求和,求平方和)
    MVC3和MVC4中CRUD操作
    SSL 中证书能否够使用IP而不是域名
    TinyXml快速入门(一)
    C++ TinyXml操作(含源码下载)
    Tinyxml 操作XML
    msxml 操作xml
    MFC中全局变量的定义及使用
    VC++中操作XMLWin32实例
  • 原文地址:https://www.cnblogs.com/bxd123/p/10430500.html
Copyright © 2011-2022 走看看