https://www.luogu.com.cn/problem/AT_arc001_2
题目描述
输入格式
无
输出格式
无
题意翻译
题目描述: 高桥君要调整空调的设定温度。现在的设定温度是A度,而他想调到B度。 空调遥控器按一次可以:
- 上调或下调1度
- 上调或下调5度
- 上调或下调10度 高桥君想求出从A调到B度的最小操作数。
输入格式: 输出以下列形式给出。
A B
0<=A,B<=40
输出格式: 输出最小操作数。
样例与说明:
样例1: 输入:
7 34
输出:
5
依次上调10、10、5、1、1度即可
样例2: 输入:
19 28
输出:
2
上调10度、下调1度即可。
样例3: 输入:
10 10
输出:
0
温度一样时无需调整。
感谢 @玉签初报明 提供的翻译。
输入输出样例
无
最短路不一定是图才有,关于“最小”都可以联想一下
乍一看跟最短路没关系,但是还是隐藏关系的
我们可以把温度看成点,每个边的权为1,求的就是最少次数,也就是最短路
如何建图?可以0~40度都遍历一遍
- 上调或下调1度
- 上调或下调5度
- 上调或下调10度
这样都可以建,把按一次遥控器能切换的温度中间连边,边权为1,表示按了一次
然后A是起点,走到B终点
本题数据量小,A与B的范围都是40,可以使用Floyd和Johnson,也可以Dijkstra和SPFA等等。
我就用Dijkstra+堆优化。
注意边界范围!
很妙
#include <bits/stdc++.h> using namespace std; const int N=45; struct node { int v, w; bool operator <(const node &A) const { return w>A.w; }; }; int x, y, dis[N], vis[N]; vector<node> a[N]; priority_queue<node> q; void dij(int s) { memset(dis, 63, sizeof dis); memset(vis, 0, sizeof vis); dis[s]=0, q.push({s, 0}); while (!q.empty()) { int u=q.top().v; q.pop(); if (vis[u]) continue; vis[u]=1; for (int i=0; i<a[u].size(); i++) { int v=a[u][i].v, w=a[u][i].w; if (!vis[v] && dis[v]>dis[u]+w) { dis[v]=dis[u]+w; q.push({v, dis[v]}); } } } } int main() { scanf("%d%d", &x, &y); for (int i=0; i<=40; i++) { if (i-1>=0) a[i].push_back({i-1, 1}), a[i-1].push_back({i, 1}); if (i-5>=0) a[i].push_back({i-5, 1}), a[i-5].push_back({i, 1}); if (i-10>=0) a[i].push_back({i-10, 1}), a[i-10].push_back({i, 1}); if (i+1<=40) a[i].push_back({i+1, 1}), a[i+1].push_back({i, 1}); if (i+5<=40) a[i].push_back({i+5, 1}), a[i+5].push_back({i, 1}); if (i+10<=40) a[i].push_back({i+10, 1}), a[i+10].push_back({i, 1}); } dij(x); printf("%d\n", dis[y]); return 0; }
标签:10,洛谷,ARC001B,int,题解,样例,back,push,dis From: https://www.cnblogs.com/didiao233/p/17993313