poj 1077 八数码

  1 #include<iostream>

  2 #include<queue>

  3 #include<algorithm>

  4 #include<string>

  5 #include<cstring>

  6 #include<cstdio>

  7 //正向广度搜索

  8 //把“x"当初0

  9 using namespace std;

 10 

 11 const int maxn = 1000000;

 12 

 13 int fac[] = { 1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880 };   //康拖展开判重

 14 //            0! 1! 2! 3!  4!  5!   6!    7!    8!      9!

 15 int vis[maxn];

 16 

 17 int get_priority(int s[]){        //康拖展开求该序列的hash值

 18     int sum = 0;

 19     for (int i = 0; i<9; i++){

 20         int cnt = 0;

 21         for (int j = i + 1; j<9; j++)

 22             if (s[i]>s[j])

 23                 cnt++;

 24         sum += (cnt*fac[9 - i - 1]);

 25     }

 26     return sum + 1;

 27 }

 28 

 29 struct node{

 30     int s[9];

 31     int loc;    //“0”的位置,把“x"当0

 32     int status;     //康拖展开的hash值

 33     string path;    //路径

 34 }start;

 35 

 36 string path;

 37 int aim = 46234;  //123456780对应的康拖展开的hash值

 38 int dir[4][2] = { { -1, 0 }, { 1, 0 }, { 0, -1 }, { 0, 1 } };//u,d,l,r

 39 char indexs[5] = "udlr";//正向搜索

 40 

 41 int BFS(){

 42     queue<node> q;

 43     while (!q.empty())

 44         q.pop();

 45     node cur, next;

 46     q.push(start);

 47     int x, y;

 48     while (!q.empty()){

 49         cur = q.front();

 50         q.pop();

 51         if (cur.status == aim){

 52             path = cur.path;

 53             return 1;

 54         }

 55         x = cur.loc / 3;

 56         y = cur.loc % 3;

 57         for (int i = 0; i<4; i++){

 58             int tx = x + dir[i][0];

 59             int ty = y + dir[i][1];

 60             if (tx<0 || tx >= 3 || ty<0 || ty >= 3)

 61                 continue;

 62             next = cur;

 63             next.loc = tx * 3 + ty;

 64             next.s[cur.loc] = next.s[next.loc];

 65             next.s[next.loc] = 0;

 66             next.status = get_priority(next.s);

 67             if (!vis[next.status]){

 68                 vis[next.status] = 1;

 69                 next.path = next.path + indexs[i];

 70                 if (next.status == aim){

 71                     path = next.path;

 72                     return 1;

 73                 }

 74                 q.push(next);

 75             }

 76         }

 77     }

 78     return 0;

 79 }

 80 

 81 int main(){

 82 

 83     //freopen("input.txt","r",stdin);

 84 

 85     char ch;

 86     while (cin >> ch){

 87         if (ch == 'x'){

 88             start.s[0] = 0;

 89             start.loc = 0;

 90         }

 91         else

 92             start.s[0] = ch - '0';

 93         for (int i = 1; i<9; i++){

 94             cin >> ch;

 95             if (ch == 'x'){

 96                 start.s[i] = 0;

 97                 start.loc = i;

 98             }

 99             else

100                 start.s[i] = ch - '0';

101         }

102         start.status = get_priority(start.s);

103         memset(vis, 0, sizeof(vis));

104         if (BFS())

105             cout << path << endl;

106         else

107             printf("unsolvable\n");

108     }

109     return 0;

110 }
BFS(G++水过 )

 

 1 void GetNode(int num, int *str) {

 2     int n = 9;

 3     int a[9];

 4     for (int i = 2; i <= n; ++i)

 5     {

 6         a[i - 1] = num%i;

 7         num = num / i;

 8         str[i - 1] = 0;

 9     }

10     str[0] = 0;

11     int rn, i;

12     for (int k = n; k >= 2; k--)

13     {

14         rn = 0;

15         for (i = n - 1; i >= 0; --i)

16         {

17             if (str[i] != 0)

18                 continue;

19             if (rn == a[k - 1])

20                 break;

21             ++rn;

22         }

23         str[i] = k;

24     }

25     for (i = 0; i<n; ++i)

26         if (str[i] == 0)

27         {

28             str[i] = 1;

29             break;

30         }

31 }
getNode

 

  1 //没看懂神牛路径怎么打印的。。QAQ

  2 # include <stdio.h>

  3 # include <string.h>

  4 

  5 # define N 9    

  6 # define MAXN (362880 + 10)

  7 

  8 typedef struct{ int k; char d; }foot;

  9 typedef struct{    char a[N]; }state;

 10 

 11 const char md[4] = {'u', 'l', 'r', 'd'};

 12 const char d[4][2] = {{-1,0}, {0,-1}, {0,1}, {1,0}};                                                    

 13 const int fact[9] = {1, 1, 2, 6, 24, 120, 720, 720*7, 720*56};

 14 

 15 state Q[MAXN/10];

 16 char vis[MAXN];

 17 foot p[MAXN];

 18 

 19 int cantor(state s)

 20 {

 21     char ch;

 22     int i, j, cnt, ret;

 23 

 24     ret = 0;

 25     for (i = 0; i < N-1; ++i)

 26     {

 27         cnt = 0;

 28         ch = s.a[i];

 29         for (j = i+1; j < N; ++j)

 30             if (s.a[j] < ch) ++cnt;

 31         ret += cnt*fact[8-i];

 32     }

 33 

 34     return ret;

 35 }

 36 

 37 char bool_inv(state s)

 38 {

 39     char ch, ret;

 40     int i, j;

 41     

 42     ret = 0;

 43     for (i = 0; i < N-1; ++i)

 44     {

 45         if ((ch = s.a[i]) == 0) continue;

 46         for (j = i+1; j < N; ++j)

 47             if (s.a[j] && s.a[j] < ch) ret = 1 - ret;

 48     }

 49     

 50     return ret;

 51 }

 52 

 53 void print_path(int x, char f)

 54 {

 55     if (p[x].k == 0) return ;

 56     if (f) putchar(md[3-p[x].d]);

 57     print_path(p[x].k, f);

 58     if (!f) putchar(md[p[x].d]);

 59 }

 60 

 61 void bfs(state start, state goal)

 62 {

 63     char t;

 64     state cur, nst;

 65     int front, rear, i;

 66     int x, y, nx, ny, ct, nt;

 67     

 68     Q[front = 1] = start;

 69     Q[rear = 2] = goal;

 70     vis[cantor(start)] = 1;

 71     vis[cantor(goal)] = 2;

 72     

 73     while (front <= rear)

 74     {

 75         cur = Q[front++];

 76         ct = cantor(cur);

 77         for (i = 0; cur.a[i] && i < N; ++i) ;

 78         x = i / 3;  y = i % 3;

 79         for (i = 0; i < 4; ++i)

 80         {

 81             nx = x + d[i][0];  ny = y + d[i][1];

 82             if (nx>=0 && nx<3 && ny>=0 && ny<3)

 83             {

 84                 nst = cur;

 85                 nst.a[x*3+y] = cur.a[nx*3+ny];

 86                 nst.a[nx*3+ny] = 0;

 87                 nt = cantor(nst);

 88                 if (!vis[nt])

 89                 {

 90                     Q[++rear] = nst;

 91                     p[nt].k = ct;

 92                     p[nt].d = i;

 93                     vis[nt] = vis[ct];

 94                 }

 95                 else if (vis[ct] != vis[nt])

 96                 {

 97                     t = (vis[ct]==1 ? 1:0);

 98                     print_path(t ? ct:nt, 0);

 99                     putchar(md[t ? i:3-i]);

100                     print_path(t ? nt:ct, 1);

101                     putchar('\n');

102                     return ;

103                 }

104             }

105         }

106     }

107 }

108 

109 int main()

110 {

111     char i, c[5];

112     state start, goal;

113 

114     for (i = 0; i < N; ++i)

115     {

116         scanf("%s", c);

117         start.a[i] = (c[0]=='x' ? 0:c[0]-'0');

118     }

119     goal.a[8] = 0;

120     for (i = 0; i < N-1; ++i)

121         goal.a[i] = i + 1;

122         

123     for (i = 0; start.a[i] == goal.a[i] && i < N; ++i) ;

124     if (i == N) puts("");

125     else if (bool_inv(start) != bool_inv(goal)) puts("unsolvable");

126     else bfs(start, goal);

127 

128     return 0;

129 }
双向BFS

 

你可能感兴趣的:(poj)