計蒜客:密碼鎖—bfs
題目描述:
現在一個緊急的任務是打開一個密碼鎖。密碼由四位數字組成,每個數字從1到9進行編號。每次可以對任何一位數字加1或減1.當將9加1時,數字變爲1,當1減1時,數字變爲9.還可以交換相鄰的數字,每一個行動記做一步。求最少步驟打開密碼鎖。
輸入格式:
第一行輸入四位數字,表示密碼鎖的初始狀態
第二行輸入四位數字,表示開鎖的密碼。
輸出格式:
輸出一個整數,即最小步驟數。
樣例輸入:
1234
2144
樣例輸出:
2
解題思路:
廣搜。
將鎖的位置看做是四維的一個座標系。和迷宮的操作依然差不多,這樣就沒有很大的難度了,只不過添加了一些操作。本質上也沒怎麼變化。
AC代碼:
//密碼鎖
#include <stdlib.h>
#include <stdio.h>
#include <algorithm>
#include <iostream>
#include <string.h>
#include <math.h>
#include <queue>
#include <vector>
using namespace std;
struct node
{
int num[4];
int step;
}first,last;
int vis[10][10][10][10];
int bfs()
{
int temp1,temp2,i,j;
node a,next;
a=first;
a.step=0;
//首元素進隊
queue<node>q;
q.push(a);
//標記首元素
vis[a.num[0]][a.num[1]][a.num[2]][a.num[3]]=1;
while(!q.empty())
{
a=q.front();
q.pop();
//退出條件
if(a.num[0]==last.num[0]&&a.num[1]==last.num[1]&&a.num[2]==last.num[2]&&a.num[3]==last.num[3])
return a.step;
//+1操作
for(int i=0;i<4;i++)
{
next=a;
next.num[i]++;
if(next.num[i]==10)
{
next.num[i]=1;
}
if(!vis[next.num[0]][next.num[1]][next.num[2]][next.num[3]])
{
vis[next.num[0]][next.num[1]][next.num[2]][next.num[3]]=1;
next.step++;
q.push(next);
}
}
//-1操作
for(int i=0;i<4;i++)
{
next=a;
next.num[i]--;
if(next.num[i]==0)
{
next.num[i]=9;
}
if(!vis[next.num[0]][next.num[1]][next.num[2]][next.num[3]])
{
vis[next.num[0]][next.num[1]][next.num[2]][next.num[3]]=1;
next.step++;
q.push(next);
}
}
//交換 ,其實兩邊都交換的話,必然重複,所以這裏可以僅僅和右邊的數交換
for(int i=0;i<3;i++)
{
next=a;
next.num[i]=a.num[i+1];
next.num[i+1]=a.num[i];
if(!vis[next.num[0]][next.num[1]][next.num[2]][next.num[3]])
{
vis[next.num[0]][next.num[1]][next.num[2]][next.num[3]]=1;
next.step++;
q.push(next);
}
}
}
}
int main()
{
//每個數字有3個狀態:1、加一 2、減一 3、與右邊相鄰交換
//當將9加1時,數字變爲1,當1減1時,數字變爲9.還可以交換相鄰的數字,每一個行動記做一步
int i;
char str1[5],str2[5];
cin>>str1>>str2;
for(i=0;i<strlen(str1);i++)
{
first.num[i]=str1[i]-'0';
last.num[i]=str2[i]-'0';
}
int ans=bfs();
cout<<ans<<endl;
return 0;
}