洛谷题解-[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;
}

 

posted @ 2024-01-28 20:43  cn是大帅哥886  阅读(77)  评论(0)    收藏  举报