Open the LockTime Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 7766 Accepted Submission(s): 3484 Problem Description Now an emergent task for you is to open a password lock. The password is consisted of four digits. Each digit is numbered from 1 to 9.
Input The input file begins with an integer T, indicating the number of test cases.
Output For each test case, print the minimal steps in one line.
Sample Input 2 1234 2144 1111 9999
Sample Output 2 4 |
题目大意:
输入两个4位数,分别代表初始数字和目标的密码,对初始数字的每一位数进行加1、减1、交换相邻数位置操作,问经过至少多少步后可以达到目标密码。
特别注意:
9加一之后是1 ,1减1之后是9 ,最后一位数和第一位数无法互换
code:
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<queue>
#define inf 0x3f3f3f3f
using namespace std;
struct node
{
int target[5];
int step;
};
char a[5],b[5];
int pass[5];
int vis[11][11][11][11]; //vis四维数组用于记录该四位数是否存在(被访问过)
int bfs()
{
bool flag;
queue<node> Q;
node tem,nex;
for(int i=0;i<4;i++)
{
tem.target[i]=a[i]-'0'; //将所给字符串转换成整型
pass[i]=b[i]-'0';
}
tem.step=0; //初始化步骤数
Q.push(tem); //将tem入队
memset(vis,0,sizeof(vis));
while(!Q.empty())
{
tem=Q.front();
Q.pop();
flag=true;
for(int i=0;i<4;i++)
{
if(tem.target[i]!=pass[i])
{
flag=false;
break;
}
}
if(flag) //符合密码
return tem.step;
for(int j=0;j<4;j++) //对数据执行加一操作
{
nex=tem;
if(tem.target[j]==9) nex.target[j]=1; //特殊情况
else nex.target[j]=tem.target[j]+1;
if(!vis[nex.target[0]][nex.target[1]][nex.target[2]][nex.target[3]])
{
vis[nex.target[0]][nex.target[1]][nex.target[2]][nex.target[3]]=1;
nex.step=tem.step+1; //操作次数加一
Q.push(nex);
}
}
for(int j=0;j<4;j++) //对数据执行减去一操作
{
nex=tem;
if(tem.target[j]==1) nex.target[j]=9; //特殊情况
else nex.target[j]=tem.target[j]-1;
if(!vis[nex.target[0]][nex.target[1]][nex.target[2]][nex.target[3]])
{
vis[nex.target[0]][nex.target[1]][nex.target[2]][nex.target[3]]=1;
nex.step=tem.step+1;
Q.push(nex);
}
}
//相邻数互换
for(int k=0;k<3;k++) //注意是k<3 因为最后一个数和第一个数无法互换
{
nex=tem;
nex.target[k]=tem.target[k+1];
nex.target[k+1]=tem.target[k];
if(!vis[nex.target[0]][nex.target[1]][nex.target[2]][nex.target[3]])
{
vis[nex.target[0]][nex.target[1]][nex.target[2]][nex.target[3]]=1;
nex.step=tem.step+1;
Q.push(nex);
}
}
}
}
//每个for循环里面的nex=tem很重要,这保证了每次操作时原来的字符串都不会改变 ,改变的都是nex
int main()
{
int n;
cin>>n;
while(n--)
{
cin>>a>>b;
cout<<bfs()<<endl;
}
return 0;
}
该题借鉴了博友的思路,贴出来自我学习一波