深搜总结:
1.判定状况模块(找目标特征,补充估价函数等)
2.变化模块(单步变化及回退)
3.退出深搜(找到目标后,除了退出目标情况外还要退出并行的状态发展)
4.迭代深搜(逐层推进)
5.逐层深搜后记得恢复所需的原状态进行退回再探
#include<bits/stdc++.h>
using namespace std;
int maxBlock,blockNum,flag,ans[50],step;
int row1[7],row2[7],line1[7],line2[7];
bool input(){
int i;
cin >> row1[0];
if(row1[0] == 0) return false;
cin >> row2[0];
cin >> row1[1] >> row2[1];
for(i = 0; i < 7; i++){
cin >> line1[i];
}
row1[2] = line1[2];
row2[2] = line1[4];
cin >> row1[3] >> row2[3];
for(i = 0; i < 7; i++){
cin >> line2[i];
}
row1[4] = line2[2];
row2[4] = line2[4];
cin >> row1[5] >> row2[5];
cin >> row1[6] >> row2[6];
return true;
}//结合几何图形输入,滚动模型可用数组 (输入复杂时可函数分块)
void circle(int a[7],int direction){
int i,temp;
if(direction == -1){
temp = a[0];
for(i = 1; i < 7; i ++) a[i-1] = a[i];
a[6] = temp;
}
else{
temp = a[6];
for(i = 6; i > 0; i --) a[i] = a[i-1];
a[0] = temp;
}
return;
}//实现单个数组滚动功能
void moveDirec(int direction){
if(direction == 0){//A操作
circle(row1,-1);
line1[2] = row1[2];
line2[2] = row1[4];
return;
}
if(direction == 1){//B操作
circle(row2,-1);
line1[4] = row2[2];
line2[4] = row2[4];
return;
}
if(direction == 2){//C操作
circle(line1,1);
row1[2] = line1[2];
row2[2] = line1[4];
return;
}
if(direction == 3){//D操作
circle(line2,1);
row1[4] = line2[2];
row2[4] = line2[4];
return;
}
if(direction == 4){//E操作
circle(row2,1);
line1[4] = row2[2];
line2[4] = row2[4];
return;
}
if(direction == 5){//F操作
circle(row1,1);
line1[2] = row1[2];
line2[2] = row1[4];
return;
}
if(direction == 6){//G操作
circle(line2,-1);
row1[4] = line2[2];
row2[4] = line2[4];
return;
}
if(direction == 7){//H操作
circle(line1,-1);
row1[2] = line1[2];
row2[2] = line1[4];
return;
}
}//结合滚动和整个图形联动效应 实现图形的单步变化模块
void moveBack(int direction){
if(direction == 0) moveDirec(5);
if(direction == 1) moveDirec(4);
if(direction == 2) moveDirec(7);
if(direction == 3) moveDirec(6);
if(direction == 4) moveDirec(1);
if(direction == 5) moveDirec(0);
if(direction == 6) moveDirec(3);
if(direction == 7) moveDirec(2);
}//dfs需要在进行返回状态而题目中的单步变换都是两两对应互逆的即写个模块对应即可
int countkind(int &maxBlock,int &blockNum)
{
int num[4]={0},k=1,kind=0;
for(int i=2;i<=4;++i)
{
num[line1[i]]++;
}
num[row1[3]]++;
num[row2[3]]++;
for(int i=2;i<=4;++i)
{
num[line2[i]]++;
}
for(int i=1;i<=3;++i)
{
if(num[i])
kind++;
}
if(num[k]<num[2])
k=2;
if(num[k]<num[3])
k=3;
maxBlock=k;
blockNum=num[k];
return kind;
}//就算当前情况的目标量:种类(判完成)主种类(输出)主个数(估价函数剪枝)
void dfs(int floor)
{
int i,kind ;
kind=countkind(maxBlock,blockNum);//初始判断局面
if(kind==1)
{
flag=1;
return;
}//处理每种情形下可否中断
if(floor >=step)
return ;
if(floor+(8-blockNum)>step)
return ;//IDA*
for(int i=0;i<8;++i)
{
moveDirec(i);//逐个操作深搜
ans[floor]=i;//记录(不必退回,同个操作可覆盖)
dfs(floor+1);
moveBack(i);//退回
if(flag==true)
return;
}
return ;
}
int main ()
{
while(input())
{
flag=0;
if(countkind(maxBlock,blockNum)==1)
{
cout<<"No moves needed"<<endl;
cout<<maxBlock<<endl;
continue;
}
step=0;
while(!flag)
{
step++;
dfs(0);
}
char ch;
for(int i=0;i<step;++i)
{
ch='A'+ans[i];
cout<<ch;
}
cout<<endl;
cout<<maxBlock<<endl;
}
return 0;
}