zoukankan      html  css  js  c++  java
  • [SCOI2005]骑士精神(IDA*)

    题面:[SCOI2005]骑士精神

    对于这道题,我们第一眼:(bfs)爆搜

    第二眼:发现事情没这么简单:这是道省选题

    第三眼:仔细一想,直接(bfs)难道不会被卡爆吗??

    第四眼:发现题目中有:“如果能在15步以内(包括15步)到达目标状态,则输出步数,否则输出-1

    好的,(IDA)*:启发式迭代加深

    (IDA)*是什么?

    其实就是在(A)*的基础上加上迭代加深

    还不知道(A)*的同学点这里

    迭代加深其实就是每次搜索的时候限制你的搜索深度,使你的搜索树的深度保持在一个较为合理的地方,使你的时间不会爆炸,这样就可以使你在全局搜索的深度很大而答案深度很小的情况下(也是使用(IDA)*的条件)快速得出答案

    在这道题中,明显可以看出,答案深度(<=15),所以我们考虑使用(IDA)*,在每次搜索是加上限制深度条件(maxstep),如果当前搜索深度(step==maxstep),就返回答案

    作为(A)*的精髓,估价函数(g(x))当然是我们思考的主要对象

    我们可以发现,这道题给出了棋盘的目标布局

    我们可以每次(dfs)将要进入下一层时,我们都对下一层的棋盘和目标棋盘进行对比,如果差异值(tot+step>maxstep),那么我们就不进入下一层

    详见代码

    #include<bits/stdc++.h>
    using namespace std;
    const int nextx[8]={1,2,2,1,-1,-2,-2,-1};
    const int nexty[8]={-2,-1,1,2,2,1,-1,-2};
    //目标棋盘
    int goal[7][7]={
    	{0,0,0,0,0,0},
    	{0,1,1,1,1,1},
    	{0,0,1,1,1,1},
    	{0,0,0,2,1,1},
    	{0,0,0,0,0,1},
    	{0,0,0,0,0,0}
    };
    char ch[6][6];
    int num[6][6];
    bool flag=0;
    int diff()//差异值
    {
    	int tot=0;
    	for(int i=1;i<=5;i++)
    	{
    		for(int j=1;j<=5;j++)
    		{
    			if(num[i][j]!=goal[i][j])tot++;
    		}
    	}
    	return tot;
    }
    bool check(int x,int y)
    {
    	return x>5||x<1||y>5||y<1;
    }
    void dfs(int step,int x,int y,int maxstep)
    {
    	if(flag)return ;
    	if(step==maxstep)
    	{
    		if(!diff())flag=1;
    		return ;
    	}
    	for(int i=0;i<8;i++)
    	{
    		int xx=x+nextx[i];
    		int yy=y+nexty[i];
    		if(check(xx,yy))continue;
    		swap(num[x][y],num[xx][yy]);
    		if(step+diff()<=maxstep)dfs(step+1,xx,yy,maxstep);
    		swap(num[x][y],num[xx][yy]);
    	}
    }
    int main()
    {
    	int t,stx,sty;
    	scanf("%d",&t);
    	while(t--)
    	{
    		flag=0;
    		for(int i=1;i<=5;i++)
    		{
    			scanf("%s",ch[i]+1);
    			for(int j=1;j<=5;j++)
    			{
    				if(ch[i][j]=='*')num[i][j]=2,stx=i,sty=j;	
    				else num[i][j]=ch[i][j]-'0';
    			}
    		}
    		for(int i=1;i<=15;i++)
    		{
    			dfs(0,stx,sty,i);
    			if(flag)
    			{
    				printf("%d
    ",i);
    				break;
    			}
    		}
    		if(!flag)puts("-1");
    	}	
    	return 0;
    }
    
  • 相关阅读:
    BZOJ 2212/BZOJ 3702
    BZOJ 4761 Cow Navigation
    BZOJ 3209 花神的数论题
    BZOJ 4760 Hoof, Paper, Scissors
    BZOJ 3620 似乎在梦中见过的样子
    BZOJ 3940 Censoring
    BZOJ 3942 Censoring
    BZOJ 3571 画框
    BZOJ 1937 最小生成树
    BZOJ 1058 报表统计
  • 原文地址:https://www.cnblogs.com/ShuraEye/p/12110852.html
Copyright © 2011-2022 走看看