题目描述:
Dr.Kong有一台高级电视机,这台电视机可以接受100个频道(从0到99编号)。电视的配套遥控器有13个按钮:
1 2 3 ↑
4 5 6 ↓
7 8 9
— 0
当按"↑"键时,当前频道编号会增加1(如果当前为99频道,则会切换到0频道)。如果按"↓"键,当前频道编号会减小1(如果当前为0频道,则会切换到99频道)。当要切换到0~9频道时,可以直接在遥控器上按相应的键。当要切换到10~99频道时,可以先按"—"键,然后按2个与频道编号相对应的数字键(即先按与频道编号的十位数字相对应的键,然后按与个位数字相对应的键)。
由于遥控器长时间的使用和某些未知原因,遥控器上的某些键已经坏了,不能再起作用了。现在你的任务是,能否告诉Dr.Kong,如何用最少的按键次数来将频道从编号X切换到编号Y。
输入描述:
第一行: N表示有N组测试数据. (1<=N<=5) 对每组测试数据有5行,前4行包含遥控器上每个按键的信息。0表示对应的键坏了,1表示对应的键可以使用.第5行包含2个整数,分别是X 和 Y (0 <= X <= 99; 0 <= Y <= 99).
输出描述:
对每组测试数据输出一行,即将频道从编号X切换到编号Y所需要的最小按键次数.如果不可能将频道从编号X 切换到编号Y,则输出-1.
样例输入:
复制
2
0 0 1 1
1 1 1 1
1 1 1
1 1
23 52
1 1 1 0
1 1 1 0
1 0 1
0 1
23 52
样例输出:
4
-1
提示:
没有提示哦
来源:
思路:简单bfs,四种情况
判断能否进行以下操作
加 代价为1
减 代价为1
换到个位数的台 代价为1
换成两位数的台 代价为3
#include<iostream>
#include<string.h>
#include<queue>
using namespace std;
const int INF = 0x3f;
int a[20], vis[110];
int bx, ex;
struct node{
int x, t;
};
int bfs(int x, int t)
{
queue<node>q;
q.push({ x, t });
while (!q.empty())
{
int x = q.front().x, t = q.front().t;
q.pop();
if (vis[x])
continue;
vis[x] = 1;
if (x == ex) //到了要看的台
return t;
if (a[10]) // ↑可以用
q.push({ (x + 1) % 100, t + 1 });
if (a[11]) // ↓可以用
{
if (x - 1 < 0)
q.push({ 99, t + 1 });
else
q.push({ x - 1, t + 1 });
}
if (a[12]) // - 可以用 那么就按三次 换个两位数的台
{
for (int i = 1; i <= 9; i++)
for (int j = 1; j <= 9; j++)
{
if (a[i] && a[j])
q.push({ i * 10 + j, t + 3 });
}
}
for (int i = 1; i <= 9; i++) // 一位数的台
if (a[i])
q.push({ i, t + 1 });
}
return -1;
}
int main(){
int t;
cin >> t;
while (t--)
{
memset(vis, 0, sizeof vis);
memset(a, 0, sizeof a);
for (int i = 1; i <= 3; i++) // 1 2 3
cin >> a[i];
cin >> a[10]; //↑
for (int i = 4; i <= 6; i++)// 4 5 6
cin >> a[i];
cin >> a[11]; //↓
for (int i = 7; i <= 9; i++)// 7 8 9
cin >> a[i];
cin >> a[12]>>a[0]; //- 0
cin >> bx >> ex;
int ans = bfs(bx, 0);
cout << ans << endl;
}
return 0;
}