0
点赞
收藏
分享

微信扫一扫

加油站问题

刘员外__ 2022-04-24 阅读 89
c++
#include <iostream>
#include <vector>

using namespace std;

int canCompeleteCircuit(vector<int> gas, vector<int> cost)
{
//思路分析
//题目是环形道路
//首先先确认一个结论:如果总的gas量大于cost,则一定有解。
//证明:
//1.当n=2时,一定可以找到一个点A,它的gas >= cost;假设另一个点为B,
//则A点可以到达B点,到达B点之后总gas量根据题设,大于B点的cost,所以也可以回到A点;
//2、当n =3时,一定可以找到两个点,它们的gas之和大于等于cost之和,把他们当作一个整体点A,
//剩余的点为B。那么根据n =2的情况,A可以到达B再返回A。对于A内部来说,它们也符合n=2的情况,所以同样可以互通
//3、当n>3时,一定可以找到n-1个点,它们的gas之和大于等于cost之和,把他们当作一个整体点A,
//剩余的点为B,那么根据n-1的情况,A可以到达B再返回A。对于A内部来说,它门他符合n-1的情况,所以同样可以
//所以,证明若gas总量大于cost,则一定有解。

//再次我们拆成支链进行分析
//从直链的开头开始,如果从哪个点开始能走到直链的末尾,那么从这个点开始就可以走完全程
//假设支链为A B C D E;

//首先我们前提条件是已经明确了从环形道路A到A的总油量大于总消耗,那么假设从A开始到不了C,那么通过画图分析可以很容易
//得出从B开始也是到不了C的结论,代码中跳跃的原因;而且此时也可以说明A到C的总消耗大于总加油量,又因为我们又有一个前提,
//A B C D E 的总加油量是大于总消耗量的,所以必定有C 到 E 总消耗小于总加油量,
//然后我们再假设从C能到E,那么从环形道路上C就能回到C,为什么呢,分析总油量和总消耗,C 到 E 总消耗必定小于(A 和 B 到不了 C 的情况下)总加油量才能从C到E
//(从C能到E是C 到 E 总消耗小于等于总加油量的充分不必要条件),

//这种情况下从C到E有剩余,剩余量一定能再回到A,因为B到不了C,所以有B到C的总加油小于总耗油,又根据前提条件,A B C D E 的总加油量是大于总消耗量的
//那么从C到A的总加油必定大于总耗油,所以只要能从C到了E,那么必定能到了A,同理分析,必定能回到C点

int canComplate = 0;
for (int i = 0; i < gas.size(); i++)
{
canComplate += gas[i] - cost[i];
}

if (canComplate < 0) return -1;//总耗油大于总加油,肯定完不成循环

//可以完成循环

//逐个遍历加油站,因为过程中有跳跃逻辑,所以并不是挨个遍历,个人感觉用while循环控制循环变量会相对方便一点
int i = 0;
int index = 0; //用来记录起始加油站的下标
int currentGasValue = 0; //用来记录当前可用的油量
while (i < gas.size())
{
currentGasValue += gas[i] - cost[i];

if (currentGasValue >= 0)
{
i++;
}
else
{
//这时候进行跳跃,重新开始尝试新的起始点能不能走到最后

currentGasValue = 0; //重置当前可用的油量为0,开始新的起始点的尝试

index = i + 1; //更新起始点的位置

i = i + 1; //开始前进,进入while循环分析该点能不能跑到最后
}
}

return index;

}
int main()
{
vector<int> gas = { 1, 2, 3, 4, 5 };
vector<int> cost = { 3, 4, 5, 1, 2 };

int index = canCompeleteCircuit(gas, cost);

cout << index << endl;

}

 

举报

相关推荐

0 条评论