zoukankan      html  css  js  c++  java
  • hdu1667 The Rotation Game(IDA*)

    题意:#字形的图形,问将中间那一块转成相同数字需要的最少步数,输出字典序最小的路径。

    分析:跟hdu2234的无题I比,相对简单一点。其实也只是估价函数好理解一点,其他都差不多,还是迭代深搜+A*,也就是IDA*。

    估价函数h()=8-max(在要求的八个位置中,1,2,3,的个数);

    很好理解,因为没转动一步,最多只能将一个位置改为正确的。所以当前状态下,剩余的最少步数=8-max(在要求的八个位置中,1,2,3,的个数);

    #include<iostream>
    #include<algorithm>
    using namespace std;
    int map[8][8],step;
    char road[100];
    int hash1[8]={3,5,3,5,5,3,5,3};
    void TurnCOL(int c,int flag)//转动列,c表示所在列,flag表示向上还是向下,1表示向上
    {
    	int t;
    	if(flag)
    	{
    		t=map[1][c];
    		for(int i=2;i<=7;i++)
    			map[i-1][c]=map[i][c];
    		map[7][c]=t;
    	}
    	else {
    		t=map[7][c];
    		for(int i=6;i>=1;i--)
    			map[i+1][c]=map[i][c];
    		map[1][c]=t;
    	}
    }
    void TurnROW(int r,int flag)//转动行,r表示所在行,flag表示向右还是向左,1表示向右
    {
    	int t;
    	if(flag)
    	{
    		t=map[r][7];
    		for(int i=6;i>=1;i--)
    			map[r][i+1]=map[r][i];
    		map[r][1]=t;
    	}
    	else {
    		t=map[r][1];
    		for(int i=2;i<=7;i++)
    			map[r][i-1]=map[r][i];
    		map[r][7]=t;
    	}
    }
    int check()
    {
    	int num[4]={0};
    	for(int i=3;i<=5;i++)
    	{
    		num[map[3][i]]++;
    		num[map[5][i]]++;
    	}
    	num[map[4][3]]++;
    	num[map[4][5]]++;
    	int t=max(num[1],max(num[2],num[3]));
    	return t;
    }
    bool dfs(int cnt)
    {
    	int t=check();
    	if(t==8 && cnt==step)
    		return true;
    	if(cnt+(8-t)>step)
    		return false;
    	char c;
    	for(int i=0;i<8;i++)
    	{
    		c=i+'A';
    		road[cnt]=c;
    		if(c=='A'|| c=='B')
    		{
    			TurnCOL(hash1[i],1);
    			if(dfs(cnt+1)) return true;
    			TurnCOL(hash1[i],0);
    		}
    		else if(c=='F'||c=='E')
    		{
    			TurnCOL(hash1[i],0);
    			if(dfs(cnt+1))return true;
    			TurnCOL(hash1[i],1);
    		}
    		else if(c=='C'||c=='D')
    		{
    			TurnROW(hash1[i],1);
    			if(dfs(cnt+1)) return true;
    			TurnROW(hash1[i],0);
    		}
    		else {
    			TurnROW(hash1[i],0);
    			if(dfs(cnt+1)) return true;
    			TurnROW(hash1[i],1);
    		}
    	}
    	return false;
    }
    int main()
    {
    	int a,b;
    	while(scanf("%d",&a)==1 && a)
    	{
    		scanf("%d",&b);
    		memset(map,0,sizeof(map));
    		map[1][3]=a;
    		map[1][5]=b;
    		for(int i=2;i<=7;i++)
    		{
    			if(i==3|| i==5)
    			{
    				for(int j=1;j<=7;j++)
    					scanf("%d",&map[i][j]);
    				continue;
    			}
    			scanf("%d %d",&map[i][3],&map[i][5]);
    		}
    		if(check()==8)
    		{
    			puts("No moves needed");
    			printf("%d\n",map[3][3]);//忘记输出这一句,WA了一次
    			continue;
    		}
    		step=1;
    		while(true)
    		{
    			if(dfs(0))
    				break;
    			step++;
    		}
    		road[step]='\0';
    		puts(road);
    		printf("%d\n",map[3][3]);
    	}
    	return 0;
    }
    
    
  • 相关阅读:
    C# 16进制与字符串、字节数组之间的转换
    多文件上传方法
    超链接如何下载文件txt,word,excel等等
    asp.net不同类型文件读取处理
    .net二进制图片存储与读取的常见方法
    c#事务
    C#中的null和数据库中的null的区别
    Asp.net中Response.Charset 与Response.ContentEncoding区别
    导出到word
    js导出word
  • 原文地址:https://www.cnblogs.com/nanke/p/2281248.html
Copyright © 2011-2022 走看看