洛谷题解-[ARC001B] リモコン (Dijkstra)
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;
}

浙公网安备 33010602011771号