sicily 简单魔板2

sicily上面的三道“简单魔板”的变形,开始以为数据变大了第一道题的解法行不通了,其实不然。网上看到用康托展开来进行存储状态的,发现其实对于这道题没能发挥康托展开的强大威力。

下面是找到别人的代码,自己加了一些注释(呜呜,我不想剽窃的。。。只是转载不了。。)
关于康托展开,百度百科讲得非常详细了,看下就知道是什么东西了,算法实现也很简单,主要是其思想。。
其实这道题没必要使用康托编码,这里没发挥它的强大作用。因为从开始状态往下一层一层的搜不会出现太多的状态(试了下1000000步
也只是一万多种状态而已,所以康托编码没太多作用对于这道题)
  1 #include<iostream>
  2 #include<string>
  3 #include<queue>
  4 #include<memory.h>
  5 using namespace std;
  6 struct Board
  7 {
  8     int x[4];
  9     int y[4];
 10     string way;
 11     const Board operator=(const Board &p)
 12     {
 13         x[0]=p.x[0];
 14         x[1]=p.x[1];
 15         x[2]=p.x[2];
 16         x[3]=p.x[3];
 17         y[0]=p.y[0];
 18         y[1]=p.y[1];
 19         y[2]=p.y[2];
 20         y[3]=p.y[3];
 21         way=p.way;
 22         return *this;
 23     }
 24 };
 25 int n;
 26 int x[4],y[4];
 27 Board q;
 28 bool isvisit[50000];//用于搜索某状态是否曾经出现过
 29 int fact[]={1,1,2,6,24,120,720,5040,40320};//8的阶乘表
 30 //康托展开
 31 int encode(Board p)
 32 {
 33     int sum=0;
 34     int cnt;
 35     int tmp[8];
 36     for(int i=0;i<4;i++)
 37     {
 38         tmp[i]=p.x[i];
 39         tmp[4+i]=p.y[i];
 40     }
 41     for(int i=0;i<7;i++)     //真正的康托展开在这里开始 
 42     {
 43         cnt=0;
 44         for(int j=i+1;j<8;j++)
 45             if(tmp[i]>tmp[j]) cnt++;      //往低位寻找比它小的数字的个数 
 46         sum+=fact[8-i-1]*cnt;     //比它小的数字数目乘以相应的阶乘 
 47     }
 48     return sum;
 49 }
 50 //a
 51 void a(Board p)
 52 {
 53     q.x[0]=p.y[0];
 54     q.x[1]=p.y[1];
 55     q.x[2]=p.y[2];
 56     q.x[3]=p.y[3];
 57     q.y[0]=p.x[0];
 58     q.y[1]=p.x[1];
 59     q.y[2]=p.x[2];
 60     q.y[3]=p.x[3];
 61     q.way=p.way+"A";
 62 }
 63 //b
 64 void b(Board p)
 65 {
 66     q.x[0]=p.x[3];
 67     q.x[1]=p.x[0];
 68     q.x[2]=p.x[1];
 69     q.x[3]=p.x[2];
 70     q.y[0]=p.y[3];
 71     q.y[1]=p.y[0];
 72     q.y[2]=p.y[1];
 73     q.y[3]=p.y[2];
 74     q.way=p.way+"B";
 75 }
 76 //c
 77 void c(Board p)
 78 {
 79     q.x[0]=p.x[0];
 80     q.x[3]=p.x[3];
 81     q.y[0]=p.y[0];
 82     q.y[3]=p.y[3];
 83     q.x[1]=p.y[1];
 84     q.x[2]=p.x[1];
 85     q.y[1]=p.y[2];
 86     q.y[2]=p.x[2];
 87     q.way=p.way+"C";
 88 }
 89 bool equal(Board p)
 90 {
 91     for(int i=0;i<4;i++)
 92     {
 93         if(p.x[i]!=x[i])
 94             return false;
 95                 if(p.y[i]!=y[i])
 96                         return false;
 97     }
 98     return true;
 99 }
100 void bfs()
101 {
102     Board p;
103     p.x[0]=1;
104     p.x[1]=2;
105     p.x[2]=3;
106     p.x[3]=4;
107     p.y[0]=8;
108     p.y[1]=7;
109     p.y[2]=6;
110     p.y[3]=5;
111     p.way="";
112     
113     queue<Board> magic;
114     isvisit[encode(p)]=true;
115     magic.push(p);
116     while(!magic.empty())
117     {
118         p=magic.front();
119         magic.pop();
120         if(p.way.size()>n)
121         {
122             cout<<"-1"<<endl;
123             return;
124         }
125         if(equal(p))
126         {
127             cout<<p.way.size()<<" "<<p.way<<endl;
128             return;
129         }
130         a(p);
131         if(!isvisit[encode(q)])
132         {
133             isvisit[encode(q)]=true;
134             magic.push(q);
135         }
136         
137         b(p);
138         if(!isvisit[encode(q)])
139         {
140             isvisit[encode(q)]=true;
141             magic.push(q);
142         }
143         
144         c(p);
145         if(!isvisit[encode(q)])
146         {
147             isvisit[encode(q)]=true;
148             magic.push(q);
149         }
150     }
151 }
152 
153 int main()
154 {
155     while(cin>>n&&n!=-1)
156     {
157         memset(isvisit,false,sizeof(isvisit));
158         cin>>x[0]>>x[1]>>x[2]>>x[3];
159         cin>>y[0]>>y[1]>>y[2]>>y[3];
160         bfs();
161     }
162     return 0;
163 }

 

posted @ 2012-09-19 09:03  晨风世界  阅读(239)  评论(0编辑  收藏  举报