常规解法

常规思路需要 O(n*n) 的时间复杂度 才能计算出来
具体做法就是 穷举,从 0-n 不停的作为出发点测试

基于常规进行优化

模拟常规代码

for i~ n {
    can[i] = 0
    for j=i;j<i+n;j++ {
        j = j %n 
        sum += oil[j] - dis[j]
        if sum < 0 {
            break 
        }
    }
   if j == i+n {
     can[i] = 1
   } 
}

我们发现 其实我们在反复探测从不同出发点是否能够走通,走通就标记一下,其实我们中间有好多次重复的计算,比如 以下标0 为起点,需要计算 0-n ,从下标1触发需要计算 1-n -0 中间绝大部分都是重复的,如何解?
因为每一次的起点是不同的,所以我们需要对起点之后每一站从新计算,才能算准油量是否足够。反过来想,如果我们将一个点作为出发点,当油量不够的时候,直接“回朔” 加上起点之前的节点的油量是否就可以规避反复的计算,但是此时,这个循环的意义会缩减为 “寻找一个点A,从这个点出发一定能到完全程?
我们得到了点A,同样的思维,我们从点A出发,如果一个点剩余静里程大于0 ,则上个点一定也能走完全程,接着想上一个点探测,如果小于0呢!则这个节点就要暂时放弃,累加/回朔上节点的上一个节点,继续探测。

完整代码

package main 
import (
    "fmt"
    "os"
    "bufio"
    "strconv"
)
func main(){
    var n int 
    fmt.Scanf("%d",&n)
    scanner := bufio.NewScanner(os.Stdin)
    scanner.Split(bufio.ScanWords)
    oil := make([]int,n)
    dis := make([]int,n)
    for i:=0;i<n;i++{
        if scanner.Scan(){
            oil[i],_ = strconv.Atoi(scanner.Text())
        }
    }
    for i:=0;i<n;i++{
        if scanner.Scan(){
            dis[i],_ = strconv.Atoi(scanner.Text())
        }
    }
    helper(oil,dis,n)
    return 
}
func helper(oil,dis []int,n int){
    //计算某个位置的静里程数
    for i:=0;i<n;i++{
        oil[i] -= dis[i]
        dis[i] = -1
    }
    start := 0
    end := 1
    ans := 0
    //第一遍查找,确定是否可以走通
    for start != end {
        if ans>=0{
            ans += oil[end]
            end = (end +1) % n
        }else{
            ans += oil[start]
            start = (start-1+n) %n
        }
    }
    //排除不合规的条件
    if ans < 0 {
        for i:=0;i<n;i++{
            fmt.Printf("%d ",0)
        }
        return 

    }
    //至此,从一个可以走通的地方不停的倒序探索,直到探索完
    cur := start;
    ans = oil[start]
    for  dis[cur] == -1 {
        //可达,探索上一个位置
        if ans >=0 {
            dis[cur] = 1
            cur = (cur -1 +n) %n
            ans = oil[cur]
        }else{ //不可达 累加上一个位置并探索
            dis[cur] = 0
            cur = (cur-1+n) %n
            ans += oil[cur]
        }

    }
    //输出结果
    for i:=0;i<n;i++{
        fmt.Printf("%d ",dis[i])
    }
    return 

}