bnuoj 1071 拼图++(BFS+康拓展开)

http://www.bnuoj.com/bnuoj/problem_show.php?pid=1071

【题意】:经过四个点的顺逆时针旋转,得到最终拼图

【题解】:康拓展开+BFS,注意先预处理,得到所有状态,然后用hash来调用存在的状态

【code】:

  1 #include <iostream>
  2 #include <stdio.h>
  3 #include <queue>
  4 #include <string.h>
  5 
  6 using namespace std;
  7 #define N 363000
  8 
  9 struct Nod
 10 {
 11     int b[10];
 12     int pos;
 13 }nd1,nd2;
 14 
 15 int fac[] = {1,1,2,6,24,120,720,5040,40320,362880};  //康拓展开用到的数组
 16  //康托展开:
 17 int cantor(int* a, int k)
 18 {
 19      int i, j, tmp, num = 0;
 20      for (i = 0; i < k; i++) {
 21          tmp = 0;
 22          for (j = i + 1; j < k; j++)
 23              if (a[j] < a[i])
 24                  tmp++;
 25          num += fac[k - i - 1] * tmp;
 26      }
 27      return num;
 28 }
 29 
 30 int mark[N],pre[N];
 31 char dir[N];
 32 int cx[]={0,0,1,1};
 33 int cy[]={0,1,1,0};
 34 
 35 void exchange(int *a,int x,int y,int n)  //旋转
 36 {
 37     int temp;
 38     if(n%2)
 39     {
 40         temp = a[3*x+y];
 41         a[3*x+y] = a[3*x+y+1];
 42         a[3*x+y+1] = a[3*(x+1)+y+1];
 43         a[3*(x+1)+y+1] = a[3*(x+1)+y];
 44         a[3*(x+1)+y] = temp;
 45     }
 46     else
 47     {
 48         temp = a[3*(x+1)+y];
 49         a[3*(x+1)+y] = a[3*(x+1)+y+1];
 50         a[3*(x+1)+y+1] = a[3*x+y+1];
 51         a[3*x+y+1] = a[3*x+y];
 52         a[3*x+y] = temp;
 53     }
 54 }
 55 
 56 void bfs(int *b)  //广度优先搜索
 57 {
 58     queue<Nod> q;
 59     memset(mark,0,sizeof(mark));
 60     memset(pre,0,sizeof(pre));
 61     memcpy(nd1.b,b,sizeof(int)*10);
 62     int i,temp;
 63     temp = cantor(b,9);
 64     mark[temp] = 1;
 65     nd1.pos = temp;
 66     q.push(nd1);
 67     while(!q.empty())
 68     {
 69         nd2 = q.front();
 70         q.pop();
 71         for(i=0;i<8;i++)
 72         {
 73             memcpy(nd1.b,nd2.b,sizeof(int)*10);
 74             exchange(nd1.b,cx[i/2],cy[i/2],i);
 75             temp = cantor(nd1.b,9);
 76             if(mark[temp]!=1)
 77             {
 78                 mark[temp] = 1;
 79                 pre[temp] = pre[nd2.pos]+1;
 80                 nd1.pos = temp;
 81                 q.push(nd1);
 82             }
 83         }
 84     }
 85 }
 86 
 87 int main()
 88 {
 89     char str[5];
 90     int a[10],b[10]={1,2,3,4,5,6,7,8,9},c[10],hash[12];
 91     bfs(b);
 92     int t;
 93     scanf("%d",&t);
 94     while(t--)
 95     {
 96         int i;
 97         for(i=0;i<9;i++)
 98         {
 99             scanf("%d",a+i);
100             hash[a[i]] = i+1; //hash
101         }
102         for(i=0;i<9;i++)
103         {
104             scanf("%d",c+i);
105             c[i] = hash[c[i]]; 
106         }
107         int temp = cantor(c,9);
108         printf("Number Of Move(s) Needed: %d
",pre[temp]);
109     }
110     return 0;
111 }
原文地址:https://www.cnblogs.com/crazyapple/p/3331961.html