zoukankan      html  css  js  c++  java
  • 【启发式搜索】【A*算法】hdu6171 Admiral

    一个舰队的目标状态如上图。红色是旗舰。然后给你初始局面,每一次决策可以把旗舰和其上一层或下一层的两个相邻的进行交换。如果能在20步内出解的话,输出最小步数;否则输出“too difficult”。

    把每个方块当成0~5的数,整个状态正好可以压缩成1个21位的6进制数,恰好可以用long long存下,可以用set / 哈希表存储。

    定义估价函数f(S)表示局面S的每个格子所在层数与它的目标状态所在层的差的绝对值之和。

    这样每一次移动最多使这个值减小2,如果这个值大于(20-已经走的步数)*2,则剪枝。

    #include<cstdio>
    #include<algorithm>
    #include<queue>
    #include<set>
    using namespace std;
    const int dx[]={1,1,-1,-1},dy[]={0,1,0,-1};
    typedef long long ll;
    typedef pair<int,int> Point;
    set<ll>S;
    int T;
    struct Node{
    	ll st;
    	Point pos;
    	int d;
    	Node(){}
    	Node(const ll &st,const Point &pos,const int &d){
    		this->st=st;
    		this->pos=pos;
    		this->d=d;
    	}
    };
    int ceng[25];
    int Abs(int x){
    	return x<0 ? (-x) : x;
    }
    int calc(ll x){
    	int res=0;
    	for(int i=0;i<=20;++i){
    		res+=Abs((int)(x%6ll)-ceng[i]);
    		x/=6;
    	}
    	return res;
    }
    queue<Node>q;
    int wei[8][8];
    ll pw[30];
    int main(){
    	int x;
    //	freopen("1001.in","r",stdin);
    //	freopen("1001.out","w",stdout);
    	pw[0]=1;
    	for(int i=1;i<=20;++i){
    		pw[i]=pw[i-1]*6ll;
    	}
    	scanf("%d",&T);
    	ceng[0]=ceng[1]=ceng[2]=ceng[3]=ceng[4]=ceng[5]=5;
    	ceng[6]=ceng[7]=ceng[8]=ceng[9]=ceng[10]=4;
    	ceng[11]=ceng[12]=ceng[13]=ceng[14]=3;
    	ceng[15]=ceng[16]=ceng[17]=2;
    	ceng[18]=ceng[19]=1;
    	ceng[20]=0;
    	int pen=20;
    	for(int i=0;i<6;++i){
    		for(int j=0;j<=i;++j){
    			wei[i][j]=pen;
    			--pen;
    		}
    	}
    	ll goal=0;
    	for(int i=0;i<6;++i){
    		for(int j=0;j<=i;++j){
    			goal=goal*6ll+(ll)i;
    		}
    	}
    	for(;T;--T){
    		S.clear();
    		ll st=0;
    		Point stapos;
    		for(int i=0;i<6;++i){
    			for(int j=0;j<=i;++j){
    				scanf("%d",&x);
    				if(x==0){
    					stapos=Point(i,j);
    				}
    				st=st*6ll+(ll)x;
    			}
    		}
    		if(st==goal){
    			puts("0");
    			continue;
    		}
    		S.insert(st);
    		bool ok=0;
    		while(!q.empty()){
    			q.pop();
    		}
    		q.push(Node(st,stapos,0));
    		while(!q.empty()){
    			Node U=q.front(); q.pop();
    //			ll now=U.st;
    //			for(int i=0;i<6;++i){
    //				for(int j=0;j<=i;++j){
    //					printf("%I64d ",now/pw[wei[i][j]]%6ll);
    //				}
    //				puts("");
    //			}
    //			puts("");
    			if(U.d>=20){
    				continue;
    			}
    			for(int i=0;i<4;++i){
    				int tx=U.pos.first+dx[i],ty=U.pos.second+dy[i];
    				if(tx>=0 && tx<=5 && ty>=0 && ty<=tx){
    					ll nextst=U.st-pw[wei[tx][ty]]*(U.st/pw[wei[tx][ty]]%6ll);
    					nextst+=pw[wei[U.pos.first][U.pos.second]]*(U.st/pw[wei[tx][ty]]%6ll);
    					int tmp=calc(nextst);
    					if(S.find(nextst)==S.end() && tmp<=(20-(U.d+1))*2){
    						if(nextst==goal){
    							ok=1;
    							printf("%d
    ",U.d+1);
    							break;
    						}
    						S.insert(nextst);
    						q.push(Node(nextst,Point(tx,ty),U.d+1));
    					}
    				}
    			}
    			if(ok){
    				break;
    			}
    		}
    		if(!ok){
    			puts("too difficult");
    		}
    	}
    	return 0;
    }
  • 相关阅读:
    流程数据库的归档
    [转载]利用老毛桃WinPE制作启动U盘安装系统
    [转载]分享日志 Word,PDF,PPT,TXT之间的转换方法
    编程书籍推荐(转)
    ArcGIS教程下载 系列 ArcMap教程下载 ArcCatlog 教程下载 等的学习资料下载 (google文档 可以直接查看 也可以下载)
    JDK 1.6 下载 地址
    (转)MapXtreme for Java 精华文章
    Java2D Tutorial(方便自己找)
    JFC:Java
    转自百度百科《OpenGL》
  • 原文地址:https://www.cnblogs.com/autsky-jadek/p/7425397.html
Copyright © 2011-2022 走看看