题目描述
N个加油站组成一个环形,给定两个长度都是N的非负数组oil和dis(N>1),oil[i]代表第i个加油站存的油可以跑多少千米,dis[i]代表第i个加油站到环中下一个加油站相隔多少千米。假设你有一辆油箱足够大的车,初始时车里没有油。如果车从第i个加油站出发,最终可以回到这个加油站,那么第i个加油站就算良好出发点,否则就不算。请返回长度为N的boolean型数组res,res[i]代表第i个加油站是不是良好出发点
规定只能按照顺时针走,也就是i只能走到i+1,N只能走到1
[要求]
时间复杂度为O(n),空间复杂度为O(1)
输入描述:
第一行一个整数N表示加油站数量。
第二行N个整数,表示oil数组。
第三行N个整数,表示dis数组。
输出描述:
输出N个整数。若第i个整数为0表示该位置不是良好出发点,为1表示该位置是良好出发点。
示例1
输入
9
4 2 0 4 5 2 3 6 2
6 1 3 1 6 4 1 1 6
输出
0 0 0 0 0 0 0 0 0
示例2
输入
8
4 5 3 1 5 1 1 9
1 9 1 2 6 0 2 0
输出
0 0 1 0 0 1 0 1
解法一:借助纯能数组
import java.io.*;
import java.util.*;
public class Main{
public static void main(String[] args) throws Exception{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int len = Integer.parseInt(br.readLine());
String[] ss1 = br.readLine().trim().split(" ");
String[] ss2 = br.readLine().trim().split(" ");
int[] oil = new int[len];
int[] dis = new int[len];
for(int i=0;i<len;i++){
oil[i] = Integer.parseInt(ss1[i]);
dis[i] = Integer.parseInt(ss2[i]);
}
boolean[] res = getRes(oil,dis);
StringBuilder sb = new StringBuilder();
for(int i=0;i<res.length;i++){
int tmp = res[i]?1:0;
sb.append(tmp+" ");
}
System.out.println(sb.toString().trim());
}
public static boolean[] getRes(int[] oil,int[] dis){
if(dis==null||oil==null||dis.length<2||dis.length!=oil.length) return null;
int init = init(oil,dis);
return init==-1?new boolean[dis.length]:enlargeArea(dis,init);
}
public static boolean[] enlargeArea(int[] dis,int init){
boolean[] res = new boolean[dis.length];
int start = init;
int end = nextIndex(init,dis.length);
long need = 0;
long rest = 0;
do{
//往后扩充已经没法扩充了
if(start!=init&&start==lastIndex(end,dis.length)){
break;
}
if(dis[start]<need){
need -= dis[start];
}else{
//试着往前进
rest += dis[start]-need;
need = 0;
while(rest>=0&&end!=start){
rest += dis[end];
end = nextIndex(end,dis.length);
}
if(rest>=0){
res[start] = true;
connectGood(dis,lastIndex(start,dis.length),init,res);
break;
}
}
start = lastIndex(start,dis.length);
}while(start!=init);
return res;
}
public static void connectGood(int[] dis,int start,int init,boolean[] res){
long need = 0;
while(start!=init){
if(dis[start]<need){
need -= dis[start];
}else{
res[start] = true;
need = 0;
}
start = lastIndex(start,dis.length);
}
}
public static int lastIndex(int init,int size){
return init==0?size-1:(init-1);
}
public static int nextIndex(int init,int size){
return init==size-1?0:(init+1);
}
public static int init(int[] oil,int[] dis){
int init = -1;
for(int i=0;i<oil.length;i++){
dis[i] = oil[i] - dis[i];
if(dis[i]>=0){
init = i;
}
}
return init;
}
}