zoukankan      html  css  js  c++  java
  • 推门游戏 The Wall Pushers(IDA*)

    这个题的大致意思:是说你可以推一面墙,但是不能推两面墙,而且也不能推墙推过边界,问你最少要多少步才能走出迷宫。

    这题的迷宫规模较小,好像可以搜索,但是直接搜又好像太慢了,所以可以用(IDA*)进行搜索。

    关于估价函数的话,显然,最少也是要走到边界才能够走出迷宫,所以估价函数就是棋子走到边界的最近值。

    由于在路途中可能会有障碍(指推不动的墙),所以估价函数一定是小于等于准确值的,正确性得到保证。

    在搜索中用二进制来记录和更改墙的位置,例如1111代表四周都有墙。

    就像这样:

    int value(int x,int y)
    {
    	return min(x-1,min(6-x,min(y-1,4-y)));
    }
    

    (IDA*)除了估价函数的构建,其他也就是一个搜索了,应该大家都会,就不在多讲。

    说几个坑点:

    1.题目中所给的数据的输入方式是反的,所以输入的时候要x,y反着输入

    2.墙后有墙不能够推墙。

    3.推了一个墙,有三个格子的墙会改变:

    在这里插入图片描述
    例如,最左边的格子的右墙被推了之后,中间格子的左墙就没有了,中间格子会多一个右墙,最右边的格子会多一个左墙,所以说有很多的地方需要更改。

    4.走出去的那一步也要计算进路径中。

    5.走的方向也有先后顺序:西北东南

    #include<bits/stdc++.h>
    using namespace std;
    int a[7][7],minn,f[4][2]={{-1,0},{0,-1},{1,0},{0,1}},tx,ty;
    bool flag;
    char ch[200],dir[4]={'W','N','E','S'};
    int value(int x,int y)//估价函数
    {
    	return min(x-1,min(6-x,min(y-1,4-y)));
    }
    bool check(int x,int y)
    {
    	if((x==1&&(!(a[x][y]&1)))||(x==6&&(!(a[x][y]&4)))||(y==1&&(!(a[x][y]&2)))||(y==4&&(!(a[x][y]&8))))
    	{
    		return 1;
    	}
    	return 0;
    }
    void dfs(int x,int y,int step,int last)//IDA*
    {
    	if(step+value(x,y)>minn||flag)
    	{
    		return;
    	}
    	if(check(x,y))//最后一步
    	{
    		flag=1;
    		if(x==1&&(!(a[x][y]&1)))
    		{
    			ch[step]='W';
    		}
    		if(x==6&&(!(a[x][y]&4)))
    		{
    			ch[step]='E';
    		}
    		if(y==1&&(!(a[x][y]&2)))
    		{
    			ch[step]='N';
    		}
    		if(y==4&&(!(a[x][y]&8)))
    		{
    			ch[step]='S';
    		}
    		cout<<ch<<endl;
    		return;
    	}
    	for(int i=0;i<4;i++)
    	{
    		int xx=x+f[i][0],yy=y+f[i][1],xxx=xx+f[i][0],yyy=yy+f[i][1];
    		if(xx<1||xx>6||yy<1||yy>4||abs(last-i)==2||((a[x][y]&(1<<i))&&(a[xx][yy]&(1<<i))))
    		{
    			continue;
    		}
    		if(a[x][y]&(1<<i))//有墙且可以推
    		{
    			a[x][y]-=(1<<i);
    			a[xx][yy]+=(1<<i)-(1<<((i+2)%4));
    			a[xxx][yyy]+=(1<<((i+2)%4));
    			ch[step]=dir[i];
    			dfs(xx,yy,step+1,i);
    			if(flag)
    			{
    				return;
    			}
    			ch[step]=0;
    			a[x][y]+=(1<<i);
    			a[xx][yy]-=(1<<i)-(1<<((i+2)%4));
    			a[xxx][yyy]-=(1<<((i+2)%4));
    		}else{
    			ch[step]=dir[i];//无墙
    			dfs(xx,yy,step+1,i);
    			if(flag)
    			{
    				return;
    			}
    			ch[step]=0;
    		}
    	}
    }
    int main()
    {
    	while(scanf("%d%d",&tx,&ty)&&(tx||ty))
    	{
    		flag=0;
    		for(int i=1;i<=4;i++)//反着输入
    		{
    			for(int j=1;j<=6;j++)
    			{
    				scanf("%d",&a[j][i]);
    			}
    		}
    		for(minn=1;;minn++)
    		{
    			memset(ch,0,sizeof(ch));
    			dfs(tx,ty,0,44);
    			if(flag)
    			{
    				break;
    			}
    		}
    	}
    	return 0;
    }
    /*
    3 1
    5 2 6 12 6 9 
    14 2 7 2 10 14 
    8 4 12 4 4 8 
    12 6 6 14 4 12 
    0 0
    */
    
  • 相关阅读:
    FCN详解
    4、2支持向量机SVM算法实践
    Matplotlib
    4、Caffe其它常用层及参数
    6、TensorFlow基础(四)队列和线程
    0、weka学习与使用
    5、Tensorflow基础(三)神经元函数及优化方法
    4、TensorFlow基础(二)常用API与变量作用域
    elsa-core:4.ASP.NET Core Server with Elsa Dashboard
    elsa-core:3.elsa 服务
  • 原文地址:https://www.cnblogs.com/2017gdgzoi44/p/12196259.html
Copyright © 2011-2022 走看看