hdu 1195(搜索)

Open the Lock

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

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<cstdio>
#include<cstring>
#include<algorithm>
#include<math.h>
#include<queue>
#include<iostream>
using namespace std;
typedef long long LL;
bool vis[10][10][10][10];
struct Node{
    int v[4];
    int step;
};
Node s,t;
bool _equal(Node a,Node b){
    for(int i=0;i<4;i++){
        if(a.v[i]!=b.v[i]) return false;
    }
    return true;
}
Node operate(int x,Node now){
    Node next;
    for(int i=0;i<4;i++){
        next.v[i] = now.v[i];
    }
    next.step=now.step+1;
    if(x<4){ ///+
        if(now.v[x]==9) next.v[x]=1;
        else next.v[x]=now.v[x]+1;
    }else if(x<8){ ///-
        if(now.v[x%4]==1) next.v[x%4]=9;
        else next.v[x%4]=now.v[x%4]-1;
    }else{ ///exchange
        int a = now.v[x%4];
        int b = now.v[x%4+1];
        next.v[x%4]=b;
        next.v[x%4+1] = a;
    }
    return next;
}
int bfs(Node s){
    memset(vis,false,sizeof(vis));
    queue <Node>q;
    vis[s.v[0]][s.v[1]][s.v[2]][s.v[3]]=true;
    q.push(s);
    s.step = 0;
    while(!q.empty()){
        Node now = q.front();
        q.pop();
        if(_equal(now,t)){
            return now.step;
        }
        for(int i=0;i<11;i++){ ///总共11种操作,[1-4]+ [1-4]- exwchange[1,2][2,3][3,4]
            Node next=operate(i,now);
            if(vis[next.v[0]][next.v[1]][next.v[2]][next.v[3]]==false){
                vis[next.v[0]][next.v[1]][next.v[2]][next.v[3]]=true;
                q.push(next);
            }
        }
    }
    return -1;
}
int main()
{
    char s1[5],s2[5];
    int tcase;
    scanf("%d",&tcase);
    while(tcase--){

        scanf("%s",s1);
        scanf("%s",s2);
        for(int i=0;i<4;i++){
            s.v[i]=s1[i]-‘0‘;
            t.v[i]=s2[i]-‘0‘;
        }
        int res = bfs(s);
        printf("%d\n",res);
    }

    return 0;
}
时间: 2024-07-31 14:29:25

hdu 1195(搜索)的相关文章

50道hdu基础搜索总结(转)

Dfs: 大部分是直接递归枚举,即求满足约束条件下的解,虽不用剪枝,但也需要代码能力. 练习递归枚举的题目: 1241       Oil Deposits (dfs的连通块个数) 1016       Prime Ring Problem 1584       蜘蛛牌(简单dfs,简单的剪枝,还有人用DP做(???)) 1426       Sudoku Killer(练习递归的好题目 or Dancing links(???)) 2510       符号三角形(打表题,写写打表程序还是不错

HDU 1195 Open the Lock (双向广搜)

题意:给你初始4个数字和目标4个数字,问是否能由初始经过变换到目标数字: 变换规则:每个数字可以加1(9+1=1)或减1(1-1=9),或交换相邻的数字(最左和最右不是相邻的). 双向广搜:分别对初始和目标数字进行广搜,vis数组用1和2标记两种已搜索的数字,用mp数组记录状态的步数. 当从前往后搜可以到达2或从后往前搜可以到达1状态则就可以了... #include<stdio.h> #include<string.h> #include<string> #inclu

hdu 5887 搜索+剪枝

Herbs Gathering Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 687    Accepted Submission(s): 145 Problem Description Collecting one's own plants for use as herbal medicines is perhaps one of t

HDU 1195 Open the Lock 双向BFS

题目链接:Open the Lock 题意:就是给定两个4位数,起始,结束.问从起始数字到达结束数字 最少变换多少步,每个数 可以+1 / -1 或交换位置,都算做是一步. 单广,双广都用了,感觉双向BFS,太棒了,HDU的这个题双向BFS时间优化的太棒了 有图,有真相! 时间优化了近9倍... PS:今天还学习一个sscanf函数,挺棒的 单搜的代码就不贴了,贴个双搜的 #include<cstdio> #include <iostream> #include<cstrin

hdu 1195 Open the Lock (bfs+优先队列)

Open the Lock Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 4253    Accepted Submission(s): 1858 Problem Description Now an emergent task for you is to open a password lock. The password is c

hdu 1195:Open the Lock(暴力BFS广搜)

mediaxyz是一位研究ffmpeg有三年的高人了,这几天一直在折腾ffmpeg中的x264,就是不知道该如何控制码率,主要是参数太多,也不知道该如何设置,在 google上search了一下,这方面的介绍为0,那就找mediaxyz请教请教吧,这些可都是经验,非常宝贵! 以下是与mediaxyz在QQ上聊天的记录,只有一部分,因为QQ把之前的谈话删除了,但基本上精髓都可这里了. mediaxyz 23:40:26你说的qsable是c->global_quality吧 Leon 23:40:

HDU 1195 Open the Lock (双宽搜索)

意甲冠军:给你一个初始4数字和目标4数字,当被问及最初的目标转换为数字后,. 变换规则:每一个数字能够加1(9+1=1)或减1(1-1=9),或交换相邻的数字(最左和最右不是相邻的). 双向广搜:分别对初始和目标数字进行广搜,vis数组用1和2标记两种已搜索的数字,用mp数组记录状态的步数. 当从前往后搜能够到达2或从后往前搜能够到达1状态则就能够了... #include<stdio.h> #include<string.h> #include<string> #in

poj 1198 hdu 1401 搜索+剪枝 Solitaire

写到一半才发现可以用双向搜索4层来写,但已经不愿意改了,干脆暴搜+剪枝水过去算了. 想到一个很水的剪枝,h函数为  当前点到终点4个点的最短距离加起来除以2,因为最多一步走2格,然后在HDU上T了,又发现再搜索过程中,这个估价函数应该是递减的(贪心),再加上这个剪枝就过了. #include<iostream> #include<cstdio> #include<cstring> #include<string> #include<list> #

hdu - 1195 Open the Lock (bfs)

http://acm.hdu.edu.cn/showproblem.php?pid=1195 这道题虽然只是从四个数到四个数,但是状态很多,开始一直不知道怎么下手,关键就是如何划分这些状态,确保每一个状态都能遍历到. 得到四个数之后,分三种情况处理,每次改变一个数之后都要加入队列,最先输出的就是步数最少. 1 #include <cstdio> 2 #include <cstring> 3 #include <queue> 4 using namespace std;