1. 程式人生 > 其它 >HDUOJ---1195Open the Lock

HDUOJ---1195Open the Lock

Open the Lock

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

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

Author

YE, Kai

Source

搜尋....bfs  這道題很經典..

規則為 +1 ,-1,兩個對調,若 9+1=1,1-1=9,同時最右邊不能和最左邊數字不能相鄰..比如 3***4,就不行

單項搜尋 

演算法..

 1 #include<iostream>
 2 #include<queue>
 3 #include<set>
 4 using namespace std;
 5 typedef struct
 6 {
 7     int data;
 8     int step;
 9 }go;
10 int dir[4]={1,10,100,1000};
11 void bfs(int st,int en)
12 {
13     int i;
14     queue<go>mat;
15     set<int>visit;  //用來儲存是否產生這個數  
16     go q,tem;
17     q.data=st;
18     q.step=0;
19     mat.push(q);
20     visit.insert(st);
21     while(!mat.empty())
22     {
23         tem=mat.front();
24         mat.pop();
25         if(tem.data==en)
26         {
27             printf("%dn",tem.step);
28             return ;
29         }
30         /*先進行+1oper*/
31         for(i=0 ;i<4;i++)
32         {
33             q=tem;
34             if((q.data/dir[i])%10==9)  q.data-=8*dir[i];
35             else
36                 q.data+=dir[i];
37                 q.step++;
38             if(visit.find(q.data)==visit.end())   //說明該狀態沒有
39             {
40                 visit.insert(q.data);
41                 mat.push(q);
42             }
43         }
44         /*進行-1 oper*/
45         for(i=0; i<4;i++)
46         {
47             q=tem ;
48             if((q.data/dir[i])%10==1)  q.data+=8*dir[i];
49                 else    q.data-=dir[i];
50                 q.step++;
51             if(visit.find(q.data)==visit.end())   //說明該狀態沒有
52             {
53                 visit.insert(q.data);
54                 mat.push(q);
55             }
56         }
57         /*對調旋轉*/
58         int aa,bb;
59         for(i=0,q=tem;i<3;i++)
60         {
61             q=tem;
62             aa=(q.data/dir[i])%10;
63             bb=(q.data/dir[i+1])%10;
64             q.data=(q.data+(bb-aa)*dir[i]+(aa-bb)*dir[i+1]);
65             q.step++;
66            if(visit.find(q.data)==visit.end())   //說明該狀態沒有
67             {
68                 visit.insert(q.data);
69                 mat.push(q);
70             }
71         }
72     }
73 };
74 
75 int main()
76 {
77     int st,en,t;
78     cin>>t;
79     while(t--)
80     {
81         scanf("%d%d",&st,&en);
82         bfs(st,en);
83     }
84     return 0;
85 }

 採用雙向廣度搜索..

其實所謂雙向廣度,就是對於兩邊,每一次擴充套件下一層,就去掃一下,看對面有沒有與之匹配的,狀態

程式碼:

  1 #include<cstdio>
  2 #include<iostream>
  3 #include<queue>
  4 #include<set>
  5 using namespace std;
  6 
  7 typedef struct
  8 {
  9     int data;
 10     int step;
 11 /* void clr(){
 12         step=0;
 13         
 14     }*/
 15 }go;
 16 const int dir[4]={1,10,100,1000};
 17 void Dbfs(int const st ,int const  en)
 18 {
 19     go tem1,tem2,q;
 20     tem1.data=st;
 21     tem2.data=en;
 22 /*    tem1.clr();
 23     tem2.clr();
 24 */ 
 25     tem1.step=tem2.step=0;
 26     set<int>sav1,sav2;
 27     sav1.insert(st);
 28     sav2.insert(en);
 29     queue<go> beg,end;
 30     int i,a,b,cnt1,cnt2;
 31     beg.push(tem1);
 32     end.push(tem2);
 33     cnt1=cnt2=0;
 34     while(!beg.empty()&&!end.empty())
 35     {
 36      //+1oper
 37      while(!beg.empty()&&cnt1==beg.front().step)
 38      {
 39          q=beg.front();
 40          beg.pop();
 41      if(sav2.find(q.data)!=sav2.end())
 42      {
 43                 //說明有交集
 44         while(end.front().data!=q.data)
 45             end.pop();
 46         printf("%dn",q.step+end.front().step);
 47         return ;
 48      }
 49         for(i=0;i<4;i++)
 50         {
 51             tem1=q;
 52             if((tem1.data/dir[i])%10==9) tem1.data-=8*dir[i];
 53             else
 54                 tem1.data+=dir[i];
 55             tem1.step++;
 56             if(sav2.find(tem1.data)!=sav2.end())
 57             {
 58                 //說明有交集
 59                 while(end.front().data!=tem1.data)
 60                     end.pop();
 61                 printf("%dn",tem1.step+end.front().step);
 62                 return ;
 63             }
 64             if(sav1.find(tem1.data)==sav1.end()) //標記
 65             {
 66                 sav1.insert(tem1.data);
 67                 beg.push(tem1);
 68             }
 69         }
 70         //-1oper
 71          for(i=0;i<4;i++)
 72          {
 73             tem1=q;
 74             if((tem1.data/dir[i])%10==1) tem1.data+=8*dir[i];
 75             else
 76                 tem1.data-=dir[i];
 77             tem1.step++;
 78             if(sav2.find(tem1.data)!=sav2.end())
 79             {
 80                 //說明有交集
 81                while(end.front().data!=tem1.data)
 82                     end.pop();
 83                 printf("%dn",tem1.step+end.front().step);
 84                 return ;
 85             }
 86             if(sav1.find(tem1.data)==sav1.end()) //標記
 87             {
 88                 sav1.insert(tem1.data);
 89                 beg.push(tem1);
 90             }
 91         }
 92         //旋轉
 93         for(i=0;i<3;i++)
 94         {
 95             tem1=q;
 96             a=(tem1.data/dir[i])%10;
 97             b=(tem1.data/dir[i+1])%10;
 98             tem1.data+=(a-b)*(dir[i+1]-dir[i]);
 99             tem1.step++;
100             if(sav2.find(tem1.data)!=sav2.end())
101             {
102                 //說明有交集
103              while(end.front().data!=tem1.data)
104                 end.pop();
105                 printf("%dn",tem1.step+end.front().step);
106                 return ;
107             }
108             if(sav1.find(tem1.data)==sav1.end()) //標記
109             {
110                 sav1.insert(tem1.data);
111                 beg.push(tem1);
112             }
113         }
114     }
115      cnt1++;
116      while(!end.empty()&&cnt2==end.front().step)
117      {
118          q=end.front();
119            end.pop();
120          //+1oper
121         for(i=0;i<4;i++)
122         {
123             tem2=q;
124             if((tem2.data/dir[i])%10==9) tem2.data-=8*dir[i];
125             else
126                 tem2.data+=dir[i];
127             tem2.step++;
128             if(sav1.find(tem2.data)!=sav1.end())
129             {
130                 //說明有交集
131                 while(beg.front().data!=tem2.data)
132                     beg.pop();
133                 printf("%dn",tem2.step+beg.front().step);
134                 return ;
135             }
136             if(sav2.find(tem2.data)==sav2.end()) //標記
137             {
138                 sav2.insert(tem2.data);
139                 end.push(tem2);
140             }
141         }
142         //-1oper
143          for(i=0;i<4;i++)
144          {
145             tem2=q;
146             if((tem2.data/dir[i])%10==1) tem2.data+=8*dir[i];
147             else
148                 tem2.data-=dir[i];
149             tem2.step++;
150             
151             if(sav1.find(tem2.data)!=sav1.end())
152             {
153                 //說明有交集
154                 while(beg.front().data!=tem2.data)
155                     beg.pop();
156                 printf("%dn",tem2.step+beg.front().step);
157                 return ;
158             }
159             if(sav2.find(tem2.data)==sav2.end()) //標記
160             {
161                 sav2.insert(tem2.data);
162                 end.push(tem2);
163             }
164         }
165         //旋轉
166         for(i=0;i<3;i++)
167         {
168             tem2=q;
169             a=(tem2.data/dir[i])%10;
170             b=(tem2.data/dir[i+1])%10;
171             tem2.data+=(a-b)*(dir[i+1]-dir[i]);
172             tem2.step++;
173             if(sav1.find(tem2.data)!=sav1.end())
174             {
175                 //說明有交集
176                 while(beg.front().data!=tem2.data)
177                     beg.pop();
178                 printf("%dn",tem2.step+beg.front().step);
179                 return ;
180             }
181             if(sav2.find(tem2.data)==sav2.end()) //標記
182             {
183                 sav2.insert(tem2.data);
184                 end.push(tem2);
185             }
186         }
187      }
188      cnt2++;
189     }
190 }
191 
192 int main()
193 {
194     int st,en,t;
195     scanf("%d",&t);
196     while(t--)
197     {
198         scanf("%d%d",&st,&en);
199         Dbfs( st , en );
200     }
201     return 0;
202 }