2021ICPC沈阳 J Luggage Lock(BFS)

链接

题目描述

Eileen has a big luggage and she would pick a lot of things in the luggage every time when A-SOUL goes out for a show. However, if there are too many things in the luggage, the 4-digit password lock on the luggage will be hard to rotate.

The state of lock is the four digits on the lock. In one step, she can choose consecutive digits to rotate up by one simultaneously or down by one simultaneously. For example, she can rotate 0000 \texttt{0000} 0000 to 0111 \texttt{0111} 0111 or 0900 \texttt{0900} 0900 in one step because the rotated digits are consecutive, but she can’t rotate 0000 \texttt{0000} 0000 to 0101 \texttt{0101} 0101 in one step. Since she has little strength, she wants to rotate the lock as few times as possible.

Now the lock is at state a 0 a 1 a 2 a 3 a_0a_1a_2a_3 a0a1a2a3 and the password is b 0 b 1 b 2 b 3 b_0b_1b_2b_3 b0b1b2b3 . As a fan of A-SOUL, you are asked to help Eileen find out the optimal plan to unlock but you only need to tell Eileen how many times she has to rotate.

输入描述:

The first line contains one integer T T T ( 1 ≤ T ≤ 1 0 5 ) (1 \leq T \leq 10^5) (1T105), denoting the numer of test cases.

Each of the test cases contains a line containing the initial state a 0 a 1 a 2 a 3 a_0a_1a_2a_3 a0a1a2a3 and the target state b 0 b 1 b 2 b 3 b_0b_1b_2b_3 b0b1b2b3.

输出描述:

For each test case, output a line containing a single integer, denoting the minimum steps needed to unlock.

输入

6
1234 2345
1234 0123
1234 2267
1234 3401
1234 1344
1234 2468

输出

1
1
4
5
1
4

思路

a 0 a 1 a 2 a 3 a_0a_1a_2a_3 a0a1a2a3 转换为 b 0 b 1 b 2 b 3 b_0b_1b_2b_3 b0b1b2b3 ,相当于从 0000 \texttt{0000} 0000 转换到 c 0 c 1 c 2 c 3 c_0c_1c_2c_3 c0c1c2c3

每次操作,相当于进行一次区间修改。从 0000 \texttt{0000} 0000 0110 \texttt{0110} 0110 就是对 [ 1 , 2 ] [1,2] [1,2] 这个区间整体加 1 1 1。每次操作,都可以选择 10 个区间:
[ 0 , 0 ] 、 [ 0 , 1 ] 、 [ 0 , 2 ] 、 [ 0 , 3 ] 、 [ 1 , 1 ] 、 [ 1 , 2 ] 、 [ 1 , 3 ] 、 [ 2 , 2 ] 、 [ 2 , 3 ] 、 [ 3 , 3 ] [0,0]、[0,1]、[0,2]、[0,3]、[1,1]、[1,2]、[1,3]、[2,2]、[2,3]、[3,3] [0,0][0,1][0,2][0,3][1,1][1,2][1,3][2,2][2,3][3,3]
对每个区间,都有 2 种拨码方法(向上或向下拨一格)。

所以,每个数 a 0 a 1 a 2 a 3 a_0a_1a_2a_3 a0a1a2a3 进行一次操作可以转换为另外 20 20 20 个数字。

0000 \texttt{0000} 0000 9999 \texttt{9999} 9999 看作一万个结点,每个结点有 20 20 20 条边,每条边的长度为 1 1 1。那么,从 0000 \texttt{0000} 0000 转换为 c 0 c 1 c 2 c 3 c_0c_1c_2c_3 c0c1c2c3 的最少步骤,就等于这张无向图上 0000 \texttt{0000} 0000 c 0 c 1 c 2 c 3 c_0c_1c_2c_3 c0c1c2c3 的最短路径。

BFS 一遍即可得到答案。

#include<bits/stdc++.h>
using namespace std;
const int power[5]={1,10,100,1000};
queue<int> que;
int f[10000],a[10],T,vis[10000];

int calc(int x,int l,int r,int k){
	for(int i=0;i<=3;i++){ a[i]=x%10; x/=10; }
	for(int i=l;i<=r;i++) a[i]=(a[i]+10+k)%10;
	for(int i=0;i<=3;i++) x+=a[i]*power[i];
	return x;
}

void solve(){
	string x,y; int num=0;
	cin>>x>>y;
	for(int i=0;i<=3;i++) x[i]=(x[i]-y[i]+10)%10;
	for(int i=0;i<=3;i++) num+=x[i]*power[3-i];
	cout<<f[num]<<"\n";
}

int main(){
	ios::sync_with_stdio(false);
	memset(f,0x3f,sizeof(f)); f[0]=0;
	que.push(0); vis[0]=1;
	while(que.size()){
		int x=que.front(); que.pop();
		for(int i=0;i<=3;i++){
			for(int j=i;j<=3;j++){
				for(int k=0;k<=1;k++){
					int y=calc(x,i,j,-2*(k==0)+1);
					f[y]=min(f[y],f[x]+1);
					if(!vis[y]) que.push(y);
					vis[y]=1;
				}
			}
		}
	}
	for(cin>>T;T;T--) solve();
}

函数 int calc(int x,int l,int r,int k) 的作用是,返回 x x x 这个数的 [ l , r ] [l,r] [l,r] 区间整体加 k k k 后得到的数字。

  • 5
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

m0_51864047

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值