优化青海湖至景点X的租车路线成本
问题描述 小F计划从青海湖出发,前往一个遥远的景点X进行旅游。景点X可能是“敦煌”或“月牙泉”,线路的路径是唯一的。由于油价的不断上涨,小F希望尽量减少行程中的燃油成本。车辆的油箱容量为400L,在起始点租车时,车内剩余油量为 200L。每行驶 1km 消耗 1L 油。沿途设有多个加油站,小F可以在这些加油站补充燃油;此外,到达目标景点X还车的时候,需要保证车内剩余的油至少有 200L。
小F需要你帮助他计算,如果合理规划加油站的加油顺序和数量,最小化从青海湖到景点X的旅行成本(元)。
输入:
distance:从青海湖到景点X的总距离(km),距离最远不超过 10000 km。 n:沿途加油站的数量 (1 <= n <= 100) gas_stations:每个加油站的信息,包含两个非负整数 [加油站距离起始点的距离(km), 该加油站的油价(元/L)] 输出:
最小化从青海湖到景点X的旅行成本(元)。如果无法到达景点X,或者到达景点X还车时油料剩余不足 200L,则需要返回 -1 告诉小F这是不可能的任务。 测试样例 样例1:
输入:distance = 500, n = 4, gas_stations = [[100, 1], [200, 30], [400, 40], [300, 20]]
输出:4300
样例2:
输入:distance = 1000, n = 3, gas_stations = [[300, 25], [600, 35], [900, 5]]
输出:-1
样例3:
输入:distance = 200, n = 2, gas_stations = [[100, 50], [150, 45]]
输出:9000
样例4:
输入:distance = 700, n = 5, gas_stations = [[100, 10], [200, 20], [300, 30], [400, 40], [600, 15]]
输出:9500
样例5:
输入:distance = 50, n = 1, gas_stations = [[25, 100]]
输出:5000
完整代码
import sys
def solution(distance, n, gasStations): maxCapacity = 400 inf = sys.maxsize
# 按照加油站位置升序排序
gasStations.sort(key=lambda x: x[0])
# 计算每个加油站之间的距离
dis = [gasStations[0][0]]
for i in range(1, len(gasStations)):
dis.append(gasStations[i][0] - gasStations[i-1][0])
# 初始化 dp 数组
dp = [[inf] * (maxCapacity + 1) for _ in range(n + 2)]
dp[0][200] = 0 # 初始状态,容量为200,花费为0
# 动态规划计算最小花费
for i in range(1, n + 1):
for j in range(maxCapacity + 1):
for k in range(maxCapacity + 1):
if j + dis[i-1] - k >= 0 and k >= dis[i-1]:
dp[i][j] = min(dp[i][j], dp[i-1][k] + (j + dis[i-1] - k) * gasStations[i-1][1])
# 判断是否可以到达终点
remaining_fuel = 200 + distance - gasStations[n-1][0]
if remaining_fuel > maxCapacity or remaining_fuel < 0:
return -1
result = inf
for i in range(remaining_fuel, maxCapacity + 1):
result = min(result, dp[n][i])
if result == inf:
return -1
return result
if name == "main":
# 测试样例
gas_stations1 = [[100, 1], [200, 30], [400, 40], [300, 20]]
gas_stations2 = [[300, 25], [600, 35], [900, 5]]
gas_stations3 = [[100, 50], [150, 45]]
gas_stations4 = [[100, 10], [200, 20], [300, 30], [400, 40], [600, 15]]
gas_stations5 = [[25, 100]]
# 测试用例
print(solution(500, 4, gas_stations1) == 4300)
print(solution(1000, 3, gas_stations2) == -1)
print(solution(200, 2, gas_stations3) == 9000)
print(solution(700, 5, gas_stations4) == 9500)
print(solution(50, 1, gas_stations5) == 5000)
找单独的数
问题描述
有一堆数字,除了一个数字,其它的数字都是成对出现。班上的每个同学拿一个数字,正好将这些数字全部拿完,问如何快速找到拿了单独数字的同学?
输入格式
- 空格分隔输入所有的数字
输出格式
- 单独的那个数字
输入样例(1)
1 1 2 2 3 3 4 5 5
输出样例(1)
4
输入样例(2)
0 1 0 1 2
输出样例(2)
2
题目思路 这道题是在一堆有重复的数中,找出那个没有重复单独的数,这是一道很简单的题。在这里,我给大家提供两种思路,下面的答案使用的是第二种思路。
第一种思路 第一种思路也是最简单,最容易理解思路,那就是统计这堆数中每一个数出现的次数,有了次数之后,我们直接找次数为1的那个数,就是我们要求的单独数了。
很容易我们就可以想到可以用key-value类型的数据结构来统计,也就是在Java中也就是HashMap(我是用Java语言写的,所以用了HashMap,其他语言可以使用自己的key-value数据结构来统计,思路是一样的)。
key是具体的数,value是数出现的次数,然后遍历数组,依次根据key将对应的value增加即可完成统计,完成统计之后,再遍历key对应的value,就value为1的key取出即可。
第二种思路 第二种思路比第一种思路简洁,且高效。我们可以使用异或来找到单独的数。如果大家忘了什么是异或,我来给大家简单介绍一下异或的特点。
异或很好理解,异嘛,就是要不一样,不一样就可以,一样那就不行。举个实际例子。a 异或 a 等于 0(a ^ a = 0)、a 异或 b 等于 a (a ^ b = a)。如果一样,就为0,不一样就为第一个数。
根据异或的这个特性,我们只需要用异或将数组遍历一遍,遇到重复时是0,而遇到我们要找的单独数时,结果就变成了我们的单独数,因为没有和单独数一样的数了,所以单独数与后面无论出现什么数异或都是单独数本身不变,这样一轮遍历我们就得出结果了。
这种思路是不是比第一种思路巧妙很多呢,我推荐大家都使用第二种思路来解这道题。虽然这道题很简单,但是用第一种思路和第二种思路体现出来的感觉还是不一样的。
public static int solution(int[] inp) {
// Edit your code here
//使用异或运算
int result = 0;
for(int p : inp){
result ^= p;
}
return result;
}
public static void main(String[] args) {
// Add your test cases here
System.out.println(solution(new int[]{1, 1, 2, 2, 3, 3, 4, 5, 5}) == 4);
System.out.println(solution(new int[]{0, 1, 0, 1, 2}) == 2);
}