BFS UVA (intermediate) 11513 - 9 Puzzle

来源:互联网 发布:免费简历解析软件 编辑:程序博客网 时间:2024/04/29 19:54

 9 Puzzle 

Alex has a puzzle her father gave her last Christmas. It has nine numbered squares arranged in a3×3 matrix (three rows and three columns) and it's mechanically designed to allow the following types of movements:

  • A horizontal right move shifts one position to the right each of the squares in the corresponding horizontal row (circularly).
  • A vertical up move shifts one position upwards each of the squares in the corresponding vertical column (circularly).


Alex's troublemaker little brother Jim snuck last night into his sister's bedroom and somehow tore the puzzle apart and put it back together. However, when Jim assembled the puzzle back, he might have done it in a configuration different from theoriginal configuration of the puzzle.


The next morning, when Alex found her puzzle had been scrambled, she called you to help her to reset her puzzle to itsoriginal configuration (shown below) as quickly as possible, so her father won't realize that the puzzle was torn and scrambled. Of course, you should do it using only valid movements, as above described.

123456789


Your task is to write a program that, given a configuration, finds a way to set the puzzle to its original configuration spending the minimum possible number of moves to accomplish it, if the given puzzle is solvable. If this is not the case, the program should point it out.

Input 

The problem input consists of several cases, each one defined by three lines that describe a puzzle configuration. That is, lines correspond to a top-down description of the rows of the given configuration, and each line consist of three digits, separated by one blank character.


The end of the input is indicated by a line with a number 0.


Output 

For each puzzle in the input, you must print a line containing S, the minimum number of moves required to set the puzzle to its original configuration, followed by a space and2*S characters indicating any sequence ofS moves that solves the puzzle.


A move is described by two characters: the first one must be H or V (H specifies a horizontal move, andV a vertical move), and the second one must be1, 2, or3 to indicate the row or the column to move.


If the puzzle is not solvable, you must output a line with the text ``Not solvable''.


Sample Input 

2 3 14 5 67 8 97 3 92 5 14 8 61 2 34 5 67 9 80

Sample Output 

1 H13 V1V3H1Not solvable

题意:有一个3x3的类似八数码这样的东西,每次能整行往右移或者整列往上移,问最少需要多少步到达目标状态。


思路:我们直接从目标状态开始转移,就是(1,2,3,4,5,6,7,8,9)开始转移,行移动变成往左移,列变成往下移,直接bfs,记录路径就行了。


代码:

#include <iostream>#include <queue>#include <cstdio>#include <cstring>#include <string>#include <string.h>#include <algorithm>#include <cassert>#include <cmath>#include <set>using namespace std;#define clr(a,x) memset(a,(x),sizeof(a));#define rep(i,a,b) for(int i=(a);i<(b);++i)#define rrep(i,a,b) for(int i=a;i>=b;--i)#define eps 1e-8#define LL long long#define mp make_pairconst int maxn=9*8*7*6*5*4*3*2+100;const int C = 3;int A[11];inline int getx(int r,int c) { return r*C+c; }inline int row(int x) { return x / C; }inline int col(int x) { return x % C; }struct Chess{    int M[C][C];    int Key;    void setKey()    {        int cnt = 0;        Key = 0;        int * a = &M[0][0];        rep(i,0,C*C) {            cnt = 0;            rep(j,i+1,C*C)            if(a[i] > a[j]) ++cnt;            Key += cnt * A[C*C-1-i];        }    }    void Upwards(int c)    {        int ch = M[C-1][c];        rrep(r,C-1,1) M[r][c] = M[r-1][c];        M[0][c] = ch;        setKey();    }    void Rightwards(int r)    {        setKey();        int ch = M[r][0];        rep(c,0,C-1) M[r][c] = M[r][c+1];        M[r][C-1] = ch;        setKey();    }    void out() const    {        rep(i,0,C) {            rep(j,0,C) printf("%2d",M[i][j]);            puts("");        }    }}in;bool read(){    rep(i,0,3) rep(j,0,3) {        scanf("%d",&in.M[i][j]);        if(in.M[i][j]==0) return false;    }    in.setKey();    return true;}char act[maxn][3];int d[maxn];Chess q[maxn];int front,rear;int pre[maxn];void output(int s){    if(s == 0) return;    printf("%s",act[s]);    output(pre[s]);}void pre_init(){    rep(i,0,C) rep(j,0,C) in.M[i][j] = getx(i,j)+1;    in.Key = 0;    clr(d,0x3f); clr(pre,-1); clr(act,0);    d[0] = 0;    front = rear = 0; q[rear++] = in;    Chess tmp,now;    while(front < rear) {        tmp = q[front++];        int u = tmp.Key;        rep(r,0,C) {            now = tmp;            now.Rightwards(r);          //  now.out(); puts("");            int v = now.Key;            if(d[v] <= d[u] + 1) continue;            d[v] = d[u] + 1;            pre[v] = u;            act[v][0] = 'H'; act[v][1] = '1'+r;            q[rear++] = now;        }        rep(c,0,C) {            now = tmp;            now.Upwards(c);            //now.out(); puts("");            int v = now.Key;            if(d[v] <= d[u] + 1) continue;            d[v] = d[u] + 1;            pre[v] = u;            act[v][0] = 'V'; act[v][1] = '1'+c;            q[rear++] = now;        }    }}void solve(){    int x = in.Key;    if(d[x] >= 100) printf("Not solvable");    else { printf("%d ",d[x]); output(x); }    printf("\n");}void Getinput(){    freopen("in.txt","w",stdout);    int a[9];    rep(i,0,9) a[i] = i;    do {        reverse(a,a+9);        rep(i,0,9) printf(" %d",a[i]+1);        reverse(a,a+9);        puts("");    } while (next_permutation(a,a+9));    puts("0");}int main(){   // Getinput(); return 0;    A[0] = 1;    clr(act,0);    rep(i,1,11) A[i] = A[i-1] * i;    pre_init();//    freopen("in.txt","r",stdin);    while(read()) {        solve();    }}




Colombia'2008
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 穿成炮灰渣妻后我和反派开农场 前任小姐姐帅又飒 弄潮1990从厂长开始 光阴之外 心动侵占 重回逃荒开端,手握空间来逆袭 重生之网红教父 蛮荒求生:反派大佬被迫种田 玄学大佬在星际重建地府 总裁又惹火夫人了 农门空间:重生娇娘撩糙汉 重生后我弃了天运之子 快穿:绑定系统后我疯狂崩人设 慕爷你虐错了夫人就是白月光 欢乐班 快穿之反派今天也在求负责 喜提娇夫:快穿作精她被迫崛起了 修真大佬都是我 唐人的餐桌 重生之大小姐她换了黑莲花剧本 重回九零做学霸 穿越星际之直播探险生活 我在古代做美食博主 小机器人每天都在劝我追校草 救命!隐婚老公当着全球撩我 仙子她一心修仙 快穿:主神他好撩人 修真界如今不太平 我与帝君虚情假意后he了 女法医她靠玄学飒翻天 蜜糖冰语 穿越年代:手握三室一厅被娇宠! 在无限游戏里疯狂求生 惊!满级玄学大佬重生后封神了 快穿之我家老祖宗是满级大佬 冤种女皇的富国指南 她真是来毁灭世界的 穿越之这个农女不简单 重生:杀神将军宁愿入赘也要娶我 被当作替身后,我虐惨了大佬 从科举开始的首辅之路