Eight(poj 1077 A*算法,八数码,vis在出队列的时候不要还原啊,否则死循环啊)

View Code
  1 //poj 1077 八数码
  2 #include <iostream>
  3 #include<cmath>
  4 #include<queue>
  5 #include<stdio.h>
  6 #include<stack>
  7 #include<stdlib.h>
  8 #include<string.h>
  9 #define M 10000000
 10 using namespace std;
 11 int fac[] = {1,1,2,6,24,120,720,5040,40320,362880};
 12 int vis[100000000] = {0,},b[4][2] = {-1,0,1,0,0,-1,0,1};  // u d l r
 13 int pre[M],move[M];
 14 int ca = 0;
 15 struct node
 16 {
 17     int n[10];
 18     int numb;
 19     int f;
 20     int g;
 21     friend bool operator < (node n1, node n2)
 22     {
 23         return n1.f > n2.f;
 24     }
 25 };
 26 
 27 int cantor(int s[])
 28 {
 29     int n = 9;
 30     int i,j,temp = 0,num = 0;
 31     for(i = 0;i<n-1;i++)
 32     {
 33         temp = 0;
 34         for(j = i+1;j<n;j++)
 35         {
 36             if(s[j]<s[i]) temp++;
 37         }
 38         num += fac[n-i-1]*temp;
 39     }
 40     return (num+1);
 41 }
 42 
 43 int geth(int ss[])
 44 {
 45     int t = 0,xx,yy,xxx,yyy;
 46     for(int i = 0;i<9;i++)
 47         if(ss[i]!=i+1)
 48         {
 49             if(ss[i] == 9) continue;
 50             xx = i/3;
 51             yy = i%3;
 52             xxx = ss[i]/3;
 53             yyy = ss[i]%3;
 54             t += abs(xx - xxx) + abs(yy - yyy);
 55         }
 56 
 57     return t;
 58 }
 59 
 60 void printt(int sss[])
 61 {
 62     stack<char> q;
 63 
 64     int p = 1,kk = cantor(sss),cc = 0;
 65     //cout<<kk<<" "<<p<<endl;
 66     while(p != kk)
 67     {
 68         //cout<<ca++<<endl;
 69         switch(move[p])
 70         {
 71             case 0: q.push('u');break;
 72             case 1: q.push('d');break;
 73             case 2: q.push('l');break;
 74             case 3: q.push('r');break;
 75         }
 76         p = pre[p];
 77         cc++;
 78        // cout<<cc<<" "<<p<<" "<<pre[p]<<endl;                //为什么总是 2  105   2   105 重复呢?
 79     }
 80     while(!q.empty())
 81     {
 82         printf("%c",q.top());
 83         q.pop();
 84     }
 85     cout<<endl;
 86 }
 87 
 88 
 89 void bfs(int ss[])
 90 {
 91     //cout<<cantor(ss)<<endl;
 92     memset(pre,-1,sizeof(pre));
 93     bool flag = false;
 94     priority_queue<node> q;
 95     while(!q.empty()) q.pop();
 96 
 97     node car;
 98     for(int i = 0;i<9;i++) car.n[i] = ss[i];
 99     car.numb = cantor(car.n);
100     car.f = geth(car.n);
101     car.g = 0;
102     q.push(car);
103     vis[car.numb] = 1;
104     while(!q.empty()&&flag == false)
105     {
106         node now = q.top();
107         q.pop();
108         //这里不用vis还原啊!!!
109         int nowx,nowy,gox,goy,nowi = 0;
110         for(nowi = 0;nowi<9;nowi++)
111         {
112             if(now.n[nowi] == 9) break;
113         }
114         nowx = nowi/3;
115         nowy = nowi%3;
116         for(int i = 0;i<4;i++)
117         {
118             if(nowx+b[i][0]>=0&&nowx+b[i][0]<3&&nowy+b[i][1]>=0&&nowy+b[i][1]<3)
119             {
120                 gox = nowx+b[i][0];
121                 goy = nowy+b[i][1];
122                 int goi = gox*3 + goy,ch = 0;
123                 node togo;
124                 for(int j = 0;j<9;j++) togo.n[j] = now.n[j];
125                 togo.f = now.f;
126                 togo.numb = now.numb;
127                 togo.g = now.g;
128 
129                 ch = togo.n[nowi];
130                 togo.n[nowi] = togo.n[goi];
131                 togo.n[goi] = ch;
132 
133                 togo.numb = cantor(togo.n);
134 
135                 if(vis[togo.numb] == 0&&togo.numb!=pre[now.numb])
136                 {
137                     togo.g = now.g + 1;
138                     togo.f = geth(togo.n) + togo.g;
139                     q.push(togo);//这里是复制还是换指针???
140                     //cout<<togo.n[6]<<togo.n[7]<<togo.n[8]<<" ";
141                     ca++;
142                     vis[togo.numb] = 1;
143                     move[togo.numb] = i;
144                     pre[togo.numb] = now.numb;
145                     //cout<<togo.numb<<" "<<pre[togo.numb]<<endl;
146                     // cout<<move[togo.numb]<<endl;
147                     if(togo.numb == 1)
148                     {
149                         flag = true;
150                        // cout<<ca<<" truue "<<togo.numb<<endl;
151                        // system("pause");
152                         break;
153                     }
154                 }
155             }
156         }
157     }
158     if(flag) printt(ss);
159     else cout<<"no"<<endl;
160 }
161 
162 
163 int main()
164 {
165     int i = 0,j = 0,a[10] = {0};
166     char s[1000] = {0};
167     gets(s);
168     for(i = 0;s[i]!='\0';i++)
169     {
170         if(s[i] == 'x')
171         {
172             a[j] = 9;
173             j++;
174         }
175         else if(s[i]>='0'&&s[i]<='9')
176         {
177             a[j] = s[i] - '0';
178             j++;
179         }
180     }
181 
182    // for(i = 0;i<3;i++)
183         //for(j = 0;j<3;j++)
184           //  cout<<fk[i][j]<<" "<<endl;
185     bfs(a);
186     return 0;
187 }

 

Eight(poj 1077 A*算法,vis在出队列的时候不要还原啊,否则死循环啊)

Time Limit: 1000MS

 

Memory Limit: 65536K

Total Submissions: 18507

 

Accepted:   8242

 

Special Judge

Description

The 15-puzzle has been around for over 100 years; even if you don't know it by that name, you've seen it. It is constructed with 15 sliding tiles, each with a number from 1 to 15 on it, and all packed into a 4 by 4 frame with one tile missing. Let's call the missing tile 'x'; the object of the puzzle is to arrange the tiles so that they are ordered as:

 1  2  3  4 
 
 5  6  7  8 
 
 9 10 11 12 
 
13 14 15  x 


where the only legal operation is to exchange 'x' with one of the tiles with which it shares an edge. As an example, the following sequence of moves solves a slightly scrambled puzzle:

 1  2  3  4    1  2  3  4    1  2  3  4    1  2  3  4 
 
 5  6  7  8    5  6  7  8    5  6  7  8    5  6  7  8 
 
 9  x 10 12    9 10  x 12    9 10 11 12    9 10 11 12 
 
13 14 11 15   13 14 11 15   13 14  x 15   13 14 15  x 
 
           r->           d->           r-> 


The letters in the previous row indicate which neighbor of the 'x' tile is swapped with the 'x' tile at each step; legal values are 'r','l','u' and 'd', for right, left, up, and down, respectively.

Not all puzzles can be solved; in 1870, a man named Sam Loyd was famous for distributing an unsolvable version of the puzzle, and
frustrating many people. In fact, all you have to do to make a regular puzzle into an unsolvable one is to swap two tiles (not counting the missing 'x' tile, of course).

In this problem, you will write a program for solving the less well-known 8-puzzle, composed of tiles on a three by three
arrangement.

Input

You will receive a description of a configuration of the 8 puzzle. The description is just a list of the tiles in their initial positions, with the rows listed from top to bottom, and the tiles listed from left to right within a row, where the tiles are represented by numbers 1 to 8, plus 'x'. For example, this puzzle

 1  2  3 
 
 x  4  6 
 
 7  5  8 


is described by this list:

 
 1 2 3 x 4 6 7 5 8 

Output

You will print to standard output either the word ``unsolvable'', if the puzzle has no solution, or a string consisting entirely of the letters 'r', 'l', 'u' and 'd' that describes a series of moves that produce a solution. The string should include no spaces and start at the beginning of the line.

Sample Input

 2  3  4  1  5  x  7  6  8 

Sample Output

ullddrurdllurdruldr

Source

South Central USA 1998

posted @ 2012-09-05 21:34  juandx  阅读(269)  评论(0编辑  收藏  举报