IDA*加深搜总结

深搜总结:

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;
 } 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值