加油站良好出发点问题

题目描述

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(n) O(n),空间复杂度为 O ( 1 ) O(1) 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
说明
如果车从A点出发,到B点且加上B的油,还剩8的油,发现到不了C;
如果从B点出发,发现车到不了C;
如果从C点出发,发现可以转一圈,所以C点是良好出发点。
……
备注:

1 ⩽ N ⩽ 1 0 5 1 \leqslant N \leqslant 10^5 1⩽N⩽105
0 ⩽ o i l [ i ] , d i s [ i ] ⩽ 1 0 9 0 \leqslant oil[i], dis[i] \leqslant 10^9 0⩽oil[i],dis[i]⩽109


题解:

贪心的思想。我们设置一个区间 [start, end) ,表示车可以从 start 开始,达到 end 的前一个位置。其中 start 我们任意挑选一个 o i l [ i ] > = d i s [ i ] oil[i] >= dis[i] oil[i]>=dis[i] 的位置开始,而 e n d = ( s t a r t + 1 ) end = (start + 1) % n end=(start+1),若车能到达,表明可以走完一圈。我们可以提前利用: o i l [ i ] − d i s [ i ] oil[i]-dis[i] oil[i]−dis[i]记录每个车站剩下的油量。

从 start 开始遍历,使用一个变量 rest 记录剩余的油量,初始值为 o i l [ s t a r t ] − d i s [ s t a r t ] oil[start] - dis[start] oil[start]−dis[start]:

  • 若 rest >= 0,尝试扩展 end ,即: r e t + = o i l [ e n d ] ; e n d = ( e n d + 1 ) ret += oil[end]; end = (end + 1) % n; ret+=oil[end];end=(end+1);
  • 若 rest < 0,向 start 左边扩展,尝试查看上一个车站能否补充现在的差额,即: s t a r t = ( s t a r t − 1 + n ) start = (start - 1 + n) % n; rest += oil[start]; start=(start−1+n);
  • 当 start == end 时停止;

若最终 rest >= 0​ ,说明 start 是一个良好出发点。对于剩下的点,我们从 start 开始往左边移动:

  • 若 rest >=0 ,说明当前位置是一个良好出发点,往左移动,继续判断上一个点,即:start = (start - 1 + n) % n; rest = oil[start];
  • 否则,当前位置不是一个良好出发点,往左寻找可能补充差额的站,即:start = (start - 1 + n) % n; rest += oil[start];
代码:
#include <cstdio>using namespace std;typedef long long LL;const int N = 100000;int oil[N];
int dis[N];
bool ret[N];int main(void) {int n;scanf("%d", &n);for ( int i = 0; i < n; ++i )scanf("%d", oil + i );int st = -1, ed;for ( int i = 0; i < n; ++i ) {scanf("%d", dis + i);oil[i] -= dis[i];if ( oil[i] >= 0 ) st = i;}if ( st == -1 ) {for ( int i = 0; i < n; ++i )printf("%d%c", ret[i], " \n"[i == n - 1]);return 0;}ed = (st + 1) % n;LL rest = oil[st];while ( st != ed ) {if ( rest >= 0 ) {rest += oil[ed];ed = (ed + 1) % n;} else {st = (st - 1 + n) % n;rest += oil[st];}}if ( rest >= 0 ) {for ( int i = 0; i < n; ++i ) {if ( rest >= 0 ) {ret[st] = 1;st = (st - 1 + n) % n;rest = oil[st];} else {ret[st] = 0;st = (st - 1 + n) % n;rest += oil[st];}}}for ( int i = 0; i < n; ++i )printf("%d%c", ret[i], " \n"[i == n - 1]);return 0;
}

加油站良好出发点问题相关推荐

  1. Leetcode 134. 加油站 解题思路及C++实现

    方法一:直接暴力方法 解题思路: 当 gas[i] >= cost[i] 时,这个加油站才可能是个出发点,遍历gas容器(数组),当出现 gas[i] >= cost[i] 时,看看以这个 ...

  2. 【详细解析】1033 To Fill or Not to Fill (25 分)

    立志用最少的代码做最高效的表达 PAT甲级最优题解-->传送门 With highways available, driving a car from Hangzhou to any other ...

  3. 滑动窗口(最大最小值)的经典例题

    滑动窗口简单概念 滑动窗口是我们假想出的一种数据结构,我们在这篇文章实现的窗口,能较快速的求区间最大最小值 在一些区间不回退的题目中运行效率也十分优秀 设窗口的左边界为l,右边界为r,(规定l< ...

  4. 【LeetCode】871. Minimum Number of Refueling Stops 解题报告(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 贪心算法 日期 题目地址:https://leetc ...

  5. 算法大神左程云耗尽5年心血分享程序员代码面试指南第2版文档

    前言 学习是一种基础性的能力.然而,"吾生也有涯,而知也无涯.",如果学习不注意方法,则会"以有涯随无涯,殆矣". 学习就像吃饭睡觉一样,是人的一种本能,人人都 ...

  6. C++贪心实现汽车加油问题

    一.实验目的 1.掌握基于贪心的算法求解汽车加油问题的原理和贪心性质的证明. 2.掌握汽车加油问题贪心算法正确性的推导过程和设计原理. 3.掌握基于贪心的算法汽车加油问题函数的具体步骤. 4.具备运用 ...

  7. 加油站的良好出发点问题

    加油站的良好出发点问题 作者:Grey 原文地址: 博客园:加油站的良好出发点问题 CSDN:加油站的良好出发点问题 题目描述 题目链接 思路 暴力解法 O(N^2) 我们可以通过生成辅助数组来验证良 ...

  8. 算法:加油站的良好出发点问题

    题目描述 N个加油站组成一个环形,给定两个长度都是N的非负数组 oil和dis(N>1),oil[i]代表 第i个加油站存的油可以跑多少千米,dis[i]代表第i个加油站到环中下一个加油站相隔 ...

  9. 【加油站的良好出发点问题】

    从哪个加油站开始可以转一圈? 弄一个arr[]=gas[]-cost[],中途累加不能小于0 public static int canCompleteCircuit(int[] gas, int[] ...

最新文章

  1. c语言file_C语言 技能提升 系列文章(七)格式化输入/输出
  2. python保存变量_python – 在代码运行之间保存变量的数据
  3. 强化学习Reinforcement Learning
  4. 【机器学习】基于LDA主题模型的人脸识别专利分析
  5. springboot的Interceptor、Filter、Listener及注册
  6. 15款免费远程控制软件下载
  7. C语言:字符数字转int
  8. 考研必备数学公式大全(数学二)(高等数学篇)
  9. 如何批量替换文件夹名称中的指定字符?
  10. python安装插件很慢_Sublime text3+python3配置及插件安装
  11. Spring Cloud Bus 使用说明
  12. AWS abbreviation
  13. java中高级面试_中高级面试常问:Java面向对象设计的六大原则
  14. 学mysql需要英语水平多高_大学英语专业挂科率高吗
  15. Kria K26 SOM 在 KV260 开发板上的使用
  16. vue全套教程(实操)
  17. Web前端性能测试方法
  18. 计算机组成原理——8086 CPU寄存器
  19. smallworld 下的magik module 的logger和service provider
  20. 基于javaweb物业管理系统的设计与实现/小区物业管理系统

热门文章

  1. python数码管绘制原理_Micropython入门四位数码管显示原理
  2. swift和c语言互相调用教程
  3. 在Ubuntu18.04系统中,安装tldr
  4. atol和stoi的用途
  5. VS CODE 微软旗下最好用的前端开发IDE编辑器+常用插件介绍
  6. 生而为人,如何过好自己的一生?
  7. java二维数组遍历后转为一维数组_java数组(一)
  8. centos nmtui 使用_CentOS7使用nmtui和nmcli配置网络
  9. AIGC:如何使用Stable Diffusion生图
  10. 【C语言】结构组成(函数、语句、注释)