MX的密码锁 (广搜)

来源:互联网 发布:低头族事故案数据调查 编辑:程序博客网 时间:2024/04/28 13:17

在赢得了友谊赛后, MX获得了无敌变身的技能,他带着技能在寒假去ZKY做了实习工,并在寒假结束之后获得了一大笔财富,MX为了不让这笔钱充公,决定将这笔私房钱藏起来,连MM也不告诉藏在哪,为此MM很是苦恼(有钱不让我花)。有一天MM在工作室偶然发现了一个小箱子,箱子上除了有一个3*3的密码锁外还写着“MX的私房钱”(MDZZ)。密码锁有以下四种操作:

1.使同一列中三个数同时向下移动一格,并使最下面的数字转动到同列第一行

2.使同一列中三个数同时向上移动一格,并使最上面的数字转动到同列最后一行

3.使同一行中三个数同时向右移动一格,并使最右面的数字转动到同行第一列

4.使同一行中三个数同时向左移动一格,并使最左面的数字转动到同行最后一列

由于密码锁潮湿生锈,每对密码锁进行一次操作需要1 min的时间,现在MX快回工作室了,MM需要将密码锁移动成初始状态来打开密码锁,但却不知道是否能赶在MX回来之前,聪明的你可以帮助MM计算最短开锁时间吗? (当开锁时间大于5时,则不能赶在MX回来之前打开,就认为密码锁无解)


如图初始状态为 294753618

目标解锁状态为123456789

输入

第一行一个数字T,表示T组输入数据 T<=10

 

接下来T行,每行包含九个数字,中间无空格隔开,表示密码锁的开始状态

输出

每组数据输出一行,一个数字,表示打开密码锁的最短时间,密码锁无解输出“impossible”

 

(当开锁时间大于5时,则不能赶在MX回来之前打开,就认为密码锁无解)

样例输入
3123456789531496827846953172
样例输出

03impossible

思路:每一层每一列都有两种方向,把这12种方向都列出来,判断步数,超过5步的就不入队列,因为最多搜5层,所以没有标记已经搜过的情况。12种改变的是下标,

例如1 2 3 4 5 6 7 8 9 第一行向左移动,得出的是2 3 1 4 5 6 7 8 9 ,1的下标是—+2,2 ,3 的下标都是-1,所以,next数组代表的是的是这个位置的数的下标的改变值。

#include<iostream>#include<cstdio>#include<cstring>#include<queue>using namespace std;struct node{int stemp;char c[10];}D,d;queue<node>q;int main(){    int t,k,i,j,ans;    char b[10]={'1','2','3','4','5','6','7','8','9'};    int next[12][10]={   {2,-1,-1,0,0,0,0,0,0},   {1,1,-2,0,0,0,0,0,0},   {0,0,0,2,-1,-1,0,0,0},   {0,0,0,1,1,-2,0,0,0},   {0,0,0,0,0,0,2,-1,-1},   {0,0,0,0,0,0,1,1,-2},   {6,0,0,-3,0,0,-3,0,0},   {3,0,0,3,0,0,-6,0,0},   {0,6,0,0,-3,0,0,-3,0},   {0,3,0,0,3,0,0,-6,0},   {0,0,6,0,0,-3,0,0,-3},   {0,0,3,0,0,3,0,0,-6}   };   scanf("%d",&t);    while(t--){   // printf("t=%d\n",t);    scanf("%s",D.c);    queue<node>q;    ans=0;    while(!q.empty()) q.pop();    D.stemp=0;    q.push(D);  //  printf("R ");    //  printf("%s %d\n",D.c,D.stemp);    while(!q.empty()){        D=q.front();        q.pop();     //   printf("C ");     //  printf("%s %d\n",D.c,D.stemp);        int f=0;        for(i=0;i<9;i++)        {          if(D.c[i]!=b[i]){            f=1;            break;          }        }        if(!f){            printf("%d\n",D.stemp);            ans=1;            break;        }        for(k=0;k<12;k++){    for(i=0;i<9;i++)        d.c[i+next[k][i]]=D.c[i];        d.stemp=D.stemp+1;        if(d.stemp<=5)        {            q.push(d);        //    printf("R ");        // printf("%s %d\n",d.c,d.stemp);        }       }    }    if(ans==0)        printf("impossible\n");}}


0 0
原创粉丝点击