杭电1195(BFS)

7 篇文章 0 订阅

Open the Lock(难度:1)

Time Limit: 2000/1000 MS (Java/Others)
Memory Limit: 65536/32768 K (Java/Others)

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.
Each time, you can add or minus 1 to any digit. When add 1 to ‘9’, the digit will change to be ‘1’ and when minus 1 to ‘1’, the digit will change to be ‘9’. You can also exchange the digit with its neighbor. Each action will take one step.

Now your task is to use minimal steps to open the lock.

Note: The leftmost digit is not the neighbor of the rightmost digit.

Input

The input file begins with an integer T, indicating the number of test cases.

Each test case begins with a four digit N, indicating the initial state of the password lock. Then followed a line with anotther four dight M, indicating the password which can open the lock. There is one blank line after each test case.

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减1后变成9,将输入的数字当做字符串处理,vis数组是四维数组。

方法:广度优先搜索。

AC代码:

#include<iostream>
#include<cstring>
#include<queue>
using namespace std;

struct node{
    int num[4];//密码锁的四位状态 
    int step;//当前步数 
};

char str[2][5];//数字当作字符串输入 
int vis[10][10][10][10];
int pwd[4];//正确密码 

//广搜 
int bfs()
{
    node cur,nex;//目前节点,下一个扩展节点 
    for(int i=0;i<4;i++)
    {
        cur.num[i]=str[0][i]-'0';
        pwd[i]=str[1][i]-'0';//把字符串映射为数字 
    } 
    memset(vis,0,sizeof(vis));
    cur.step=0;
    queue<node>q;
    q.push(cur);
    int lock;//判断是否为正确密码 
    while(!q.empty())//当前队列仍有元素可扩展 
    {
        cur=q.front();//得到队头状态 
        q.pop();//从队列中弹出队头状态 
        lock=1;//初始化为1 
        for(int i=0;i<4;i++)//与密码不同lock=0 
        {
            if(cur.num[i]!=pwd[i])
            {
                lock=0;
                break;
            }
        }
        if(lock)//lock=1代表与密码相同 
        {
            return cur.step;
        }
        for(int i=0;i<4;i++)//+
        {
            nex=cur;
            if(cur.num[i]==9) nex.num[i]=1;//9加1为1 
            else nex.num[i]=cur.num[i]+1;//其他正常加1 
            if(!vis[nex.num[0]][nex.num[1]][nex.num[2]][nex.num[3]])
            {
                vis[nex.num[0]][nex.num[1]][nex.num[2]][nex.num[3]]=1;
                nex.step=cur.step+1;
                q.push(nex); 
            }
        }
        for(int i=0;i<4;i++)//- 
        {
            nex=cur;
            if(cur.num[i]==1) nex.num[i]=9;//1减1为9
            else nex.num[i]=cur.num[i]-1;//其他正常减1 
            if(!vis[nex.num[0]][nex.num[1]][nex.num[2]][nex.num[3]])
            {
                vis[nex.num[0]][nex.num[1]][nex.num[2]][nex.num[3]]=1;
                nex.step=cur.step+1;
                q.push(nex); 
            }
        }
        for(int i=0;i<3;i++)//交换 
        {
            nex=cur;
            nex.num[i]=cur.num[i+1];
            nex.num[i+1]=cur.num[i];
            if(!vis[nex.num[0]][nex.num[1]][nex.num[2]][nex.num[3]])
            {
                vis[nex.num[0]][nex.num[1]][nex.num[2]][nex.num[3]]=1;
                nex.step=cur.step+1;
                q.push(nex); 
            }
        }
    }
}

int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        cin>>str[0]>>str[1];
        cout<<bfs()<<endl;
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值