hrbust 1616 密码锁(广搜)

分析:广搜,每个四位数作为一个状态,从每个状态扩展出其他的几种状态并累加步数之后加入队列。

  1 #include <stdio.h>
  2 #include <string.h>
  3 #include <algorithm>
  4 using namespace std;
  5 
  6 int vis[10][10][10][10];  //标记数组
  7 
  8 struct node
  9 {
 10     int step;
 11     int num[4];
 12 }q[8000], tt, in, st, end;
 13 int front,rear;
 14 
 15 bool ok(node t)     // 满足条件
 16 {
 17     if (vis[t.num[0]][t.num[1]][t.num[2]][t.num[3]] == 0)
 18     {
 19         vis[t.num[0]][t.num[1]][t.num[2]][t.num[3]] = 1;  //访问之后标记之
 20         return true;
 21     }
 22     else return false;
 23 }
 24 
 25 void inq1(node t,int d)      //第一种方式入队
 26 {
 27      t.num[d] = (t.num[d]==9?1:t.num[d]+1);
 28      if (ok(t)){
 29         q[rear++] = t;
 30      }
 31 }
 32 void inq2(node t,int d)     //第二种方式入队
 33 {
 34      t.num[d] = (t.num[d]==1?9:t.num[d]-1);
 35      if (ok(t)){
 36         q[rear++] = t;
 37      }
 38 }
 39 void inq3(node t,int d)     //第三种方式入队
 40 {
 41     swap(t.num[d],t.num[d+1]);
 42     if (ok(t)){
 43         q[rear++] = t;
 44     }
 45 }
 46 
 47 void solve()
 48 {
 49     int res = 0;
 50     int i, j;
 51 
 52     front=0;
 53     rear=0;
 54     memset(vis,0,sizeof(vis));
 55 
 56     st.step = 0;
 57     ok(st);
 58     q[rear++] = st;
 59 
 60     while (front < rear)
 61     {
 62         tt = q[front++];
 63         if (tt.num[0]==end.num[0] && tt.num[1]==end.num[1]
 64          && tt.num[2]==end.num[2] && tt.num[3]==end.num[3]){
 65             res = tt.step;
 66             break;
 67         }
 68 
 69         tt.step++;             //累加步数
 70         for (i=0; i<4; i++)
 71         {
 72             inq1(tt,i);
 73             inq2(tt,i);
 74         }
 75         for (i=0; i<3; i++)
 76         {
 77             inq3(tt,i);
 78         }
 79     }
 80     printf("%d\n",res);
 81 }
 82 
 83 void up(node &t,int &p)
 84 {
 85     t.num[3] = p%10;
 86     t.num[2] = (p/10)%10;
 87     t.num[1] = (p/100)%10;
 88     t.num[0] = p/1000;
 89 }
 90 
 91 int main()
 92 {
 93     int ca;
 94     int i, j;
 95     int a, b;
 96     scanf("%d",&ca);
 97     while (ca--)
 98     {
 99         scanf("%d %d",&a,&b);
100 
101         up(st,a);
102         up(end,b);
103 
104         solve();
105     }
106     return 0;
107 }

 

密码锁
Time Limit: 1000 MS Memory Limit: 32768 K
Total Submit: 17(9 users) Total Accepted: 13(9 users) Rating:  Special Judge: No
Description

Ikki希望自己可以有一台相机。

终于有一天,ikki发现自己的小金库已经足够买一台相机了,于是打算将其清空之~

但是小金库上有一个神奇的锁,这个锁一共是四位,每位都是编号从19。每次可以有三种操作选择:

1、将四位数中的某一位加上1,如果该数之前是9的话则变成1.

2、将四位数中的某一位减去1,如果该数之前是1的话则变成9 .

3、将相邻的数字调换位置,注意第一个数字和第四个数字不算相邻

现在ikki想知道至少操作多少次可以打开这个锁。

 

Input

第一行一个整数T,表示有T组测试数据。

每组测试数据的第一行有两个四位整数NM,分别表示锁现在表示的数字和能够打开锁的数字。

Output

每组数据输出一行,表示操作的最少的次数。

Sample Input
2 
1234 2144
1111 9999
Sample Output
2
4

posted @ 2013-03-04 19:36  尔滨之夏  阅读(344)  评论(0编辑  收藏  举报