hdu1813 IDA*算法

這道題的題意是:從棋子上的任意一點(邊緣、壞的棋子除外),都能按照某一指令走到邊緣,求這個最短的指令。

 

一開始看到這個題的時候一點思路也沒有,後來看了一下別人的解題報告,才明白用的是IDA*算法,IDA*算法就是A*算法+迭代。

解題思路爲:

1.用BFS求出棋子上所有點到邊緣的距離

2.用A*算法進行預先判斷,A*算法是預先判斷的算法,不同於dfs和bfs這種盲目搜索算法,他可以大大的減少時間的複雜度,如果當前節點的深度+當前狀態下棋子上任意一節點到邊緣的最大值>確定的最大深度,則return false。

3.運用迭代一次加深進行搜索,最大深度從1開始搜索,一直到找到爲止。

 

代碼參考的論壇上某一大神的代碼:

#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;

#define inf 1<<30;
typedef pair<int,int>PP;


struct Node{
	int x,y;
}node[44];

char str[11][11];
int map[11][11],Index[1111],dist[11][11];
int n,m,maxdeep;
int dir[4][2]={{0,1},{-1,0},{1,0},{0,-1}};

bool In_Edge(int x,int y){
	if(x==1||x==n||y==1||y==n)
	return true;
	return false;
}

//bfs用來求到邊緣的最短長度 
int bfs(int x,int y){
	queue<PP>que;
	que.push(make_pair(x,y));
	int dd[11][11];
	memset(dd,-1,sizeof(dd));
	dd[x][y]=0;
	while(!que.empty()){
		x=que.front().first,y=que.front().second;
		que.pop();
		if(In_Edge(x,y))
		return dd[x][y];
		
		for(int i=0;i<4;i++){
			int xx=x+dir[i][0],yy=y+dir[i][1];
			if(map[xx][yy]&&dd[xx][yy]==-1){
				dd[xx][yy]=dd[x][y]+1;
				que.push(make_pair(xx,yy));
			}
		}
	}
	return -1;
}

int Get_H(Node node[]){
	int max_dist=0;
	for(int i=0;i<m;i++){
		max_dist=max(max_dist,dist[node[i].x][node[i].y]);
	}
	return max_dist;
}


bool IDA_star(int deep,Node node[]){
	//A*剪枝 
	if(Get_H(node)+deep>maxdeep)
	return false;
	
	if(deep==maxdeep)
	return true;
	
	Node tmp_node[44];
	for(int i=0;i<4;i++){
		Index[deep]=i;
		
		for(int j=0;j<m;j++){
			int xx=node[j].x+dir[i][0],yy=node[j].y+dir[i][1];
			//如果這個方向不能繼續往下走 
			if(In_Edge(node[j].x,node[j].y)||map[xx][yy]==0){
				tmp_node[j]=node[j];
			}
			//這個方向能繼續走 
			else
			tmp_node[j].x=xx,tmp_node[j].y=yy;
		}
		if(IDA_star(deep+1,tmp_node))
		return true;
	}
	return false; 
	
}


int main(){
	int t=0;
	
	while(scanf("%d",&n)!=EOF){
		if(t++){
			puts("");
		}
		
		for(int i=1;i<=n;i++){
			scanf("%s",str[i]+1);
			for(int j=1;j<=n;j++)
			map[i][j]=1-(str[i][j]-'0');
		}
		
		
		m=0;
	
		for(int i=1;i<=n;i++){
			for(int j=1;j<=n;j++){
				if(map[i][j]){
					if(In_Edge(i,j))
					dist[i][j]=0;
					else{
						dist[i][j]=bfs(i,j);
						node[m].x=i,node[m++].y=j;
					}
				}
				else{
					dist[i][j]=inf;
				}
				
			}
		}
	    
		if(m==0)
		continue;
		for(maxdeep=1;;maxdeep++){
			if(IDA_star(0,node))
			break;
		}
		
		for(int i=0;i<maxdeep;i++){
			if(Index[i]==0)
			puts("east");
			else if(Index[i]==1)
			puts("north");
			else if(Index[i]==2)
			puts("south");
			else if(Index[i]==3)
			puts("west");
		}
	}
	return 0;
}


 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章