HDU--杭电--1195--Open the Lock--深搜--忘记说句话装逼了,都是什么双向广搜,不知道怎么想的,直接就是一个深搜的水题好不好?

这个题我看了,都是推荐的神马双向广搜,难道这个深搜你们都木有发现?还是特意留个机会给我装逼?

Open the Lock

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 3014    Accepted Submission(s): 1323


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

 

#include <iostream>
#include <cstring>
#include <cmath>
using namespace
std;
int
visit[4]={0},ss,a[4],b[4];  //visit记录a[i]是否被访问,ss用来记录暴力过程中的最小值
int
cmp(int s)  //这个是用来记录从当前这样的状态不左右移动最少要多少次
{

    int
i,sum,aa[4]={s/1000,s/100%10,s/10%10,s%10};  //因为进来的是一个数字,所以用数组把它阉了,嘿嘿
    for
(
i=sum=0;i<4;i++)  //一位一位的开锁
    {

        if
(
abs(aa[i]-b[i])<5)sum+=abs(aa[i]-b[i]);
        else
sum+=9-abs(aa[i]-b[i]);
    }
return
sum;
}

void
dfs(int sum,int s)  //dfs里面进来的sum是当前的这个合成的数字,也就是不停移动得到的数组,s是记录移动次数
{

    int
i;
    if
(
sum>999)  //当sum>999也就是说sum是一个四位数时说明新的那个开锁初始状态OK了
    {

        i=cmp(sum)+s;  //这时把sum和数组b开锁的次数和用s记录的移动的次数记录下来
        if
(
i<ss)ss=i;  //比较,ss记录最小开锁操作
        return
;
    }

    for
(
i=0;i<4;i++)
    {

        if
(!
visit[i])
        {

            visit[i]=1;
            dfs(sum*10+a[i],s++);  //要是你聪明,会看到这里的一个重要的步骤,就是s++,别小看了,这说明下一次再在for循环里面取数就是在这次的数移动一位得到的,本体就是这个才是重点呢
            visit[i]=0;
        }
    }
}

int
main (void)
{

    int
i,j,k,l,n,m,t;
    cin>>t;
    while
(
t--&&cin>>n>>m)
    {

        for
(
i=3,j=1;i>=0;i--,j*=10)
        {

            a[i]=n/j%10;
            b[i]=m/j%10;
        }

        ss=99999;
        dfs(0,0);
        cout<<ss<<endl;

    }
    return
0;
}

       是不是水题?不是你就抽我,我擦!

最后发泄一下,妹的都说马化腾坑爹,这题目也坑啊,说什么每个case后面都空一行,就是输入最后一句啊,本人英语不行,所以先是全部输出ss后用两个endl,擦,说我PE,然后我控制,第二个endl我加个if(t)这就是控制只有两个输出之间有空格,妹的还是PE,好吧,我一怒之下就冲向我那个把这个鸟题过了的兄弟,调出代码,输入...输出...输入...输出...最后他说,空行是自己输入的......................我晕倒....

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值