题目分析:
简单魔板由于N比较小,所以可以用暴力DFS,但是这个题目N比较大,所以要进行状态判断
一共有8!个状态,需要把这些状态对应到整数上去,正好是康拓展开
所以本题DFS+康拓展开
#include<iostream> #include <iomanip> #include<stdio.h> #include<cmath> #include<iomanip> #include<list> #include <map> #include <vector> #include <string> #include <algorithm> #include <sstream> #include <stack> #include<queue> #include<string.h> #include<set> using namespace std; int N; char initdata[2][4]={{'1','2','3','4'},{'8','7','6','5'}}; char goal[2][4]; typedef struct STATUS { vector<char> oper; unsigned deep; char data[2][4]; }Status; int factory[8] = { 0, 1, 2, 6, 24, 120,720, 5040}; bool code[40321];//共有这么多个状态 int encode(char data[][4])//康托展开 { int sum=0; for(int i=0;i<8;i++) { int count=0; for(int j=i+1;j<8;j++) { if(data[j/4][j%4]<data[i/4][i%4]) count++; } sum+=count*factory[8-i-1]; } return sum; } bool equal(char data[][4]) { for(int i=0;i<2;i++) { for(int j=0;j<4;j++) { if(data[i][j]!=goal[i][j]) return false; } } return true; } int main() { while(cin>>N&&N!=-1) { for(int i=0;i<8;i++) cin>>goal[i/4][i%4]; queue<Status> qu;//表示深度 Status st; st.deep=N; memcpy(st.data,initdata,sizeof(initdata)); memset(code,0,sizeof(code)); code[encode(initdata)]=true; qu.push(st); bool flag=false; while(!qu.empty()) { Status to=qu.front(); qu.pop(); if(equal(to.data)) { cout<<to.oper.size()<<" "; for(int i=0;i<to.oper.size();i++) cout<<to.oper[i]; cout<<endl; flag=true; break; } if(to.deep<=0) continue; Status op; op.deep=to.deep-1; memcpy(op.data,to.data,sizeof(initdata)); for(int i=0;i<4;i++)//A操作 swap(op.data[0][i],op.data[1][i]); op.oper=to.oper; op.oper.push_back('A'); int cc=encode(op.data); if(code[cc]==false) { qu.push(op); code[cc]=true; } memcpy(op.data,to.data,sizeof(initdata)); for(int i=0;i<2;i++)//B操作 { char tmp=op.data[i][3]; for(int j=3;j>0;j--) { op.data[i][j]=op.data[i][j-1]; } op.data[i][0]=tmp; } op.oper=to.oper; op.oper.push_back('B'); cc=encode(op.data); if(code[cc]==false) { qu.push(op); code[cc]=true; } memcpy(op.data,to.data,sizeof(initdata)); char tmp=op.data[0][1]; op.data[0][1]=op.data[1][1]; op.data[1][1]=op.data[1][2]; op.data[1][2]=op.data[0][2]; op.data[0][2]=tmp; op.oper=to.oper; op.oper.push_back('C'); cc=encode(op.data); if(code[cc]==false) { qu.push(op); code[cc]=true; } } if(flag==false) cout<<-1<<endl; } }