1. 程式人生 > >[DFS] Curling 2.0 POJ

[DFS] Curling 2.0 POJ

然後圖上有不能到的點(牆),起點扔一個球,球只能砸到牆才能停止,但是砸到牆上之後,這個牆就沒了,最多可以砸10次,扔出界就算輸,能不能把這個球從起點扔到終點。 注意,要是該點緊挨著就是一個牆,那就不能往這個牆的方向上扔。 一開始想用廣度優先搜尋的,但是因為要每次撞完之後牆就消失了,所以感覺還是深度優先順序寫起來方便一些,要使用bfs的話,有可能到一個點用相同的步數但是有不同的扔法,這就導致了兩種辦法消失的牆不一樣。總是實現起來是夠麻煩的 然後 超時了 這地對深度有一個限制 顯然DFS 不怕炸了 不過我還是寫了發BFS 果然係數太大 tle了

猛然回頭看著題 限制讓我想起了迭代加深 聽起來蠻高大上 實際上用起來很方便

dfs AC程式碼

#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <list> 
using namespace std;
typedef long long ll;

const int
maxn = 25 ; const int mod = 1e9+7; const int INF = 0x3f3f3f3f; const double PI=acos(-1.0); const int cx[]={1,0,-1,0}; const int cy[]={0,1,0,-1}; int n,m,x; int mp[maxn][maxn]; bool vis[maxn][maxn]; int ans; struct point{ pair<int,int> P; int sp; }st,ed; bool check(int x,int y){ return (x==ed.
P.first)&&(y==ed.P.second); } void dfs(int x, int y, int deep) { if (deep >= 10 || deep>=ans) return ; for (int i = 0;i < 4;++i) { int nx = x, ny = y; while (mp[nx + cx[i]][ny + cy[i]] == 0){ nx = nx + cx[i], ny = ny + cy[i]; if (check(nx,ny)){ ans=min(ans,deep+1);return; } } // 確定不直接碰牆 if ((mp[nx + cx[i]][ny + cy[i]] == -1) || (nx == x && ny == y)) continue; mp[nx + cx[i]][ny + cy[i]] = 0;// 改變 dfs(nx, ny, deep + 1); mp[nx + cx[i]][ny + cy[i]] = 1; // 回溯 } return ; } int main(){ while(scanf("%d %d",&m,&n)!=EOF&&m+n){ ans=INF; memset(mp,-1,sizeof(mp)); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++){ scanf("%d",&x); if(x==0) mp[i][j]=0; else if(x==1) mp[i][j]=1; else if(x==2){mp[i][j]=0; st.P.first=i;st.P.second=j;} else{mp[i][j]=0;ed.P.first=i;ed.P.second=j;} } dfs(st.P.first,st.P.second,0); printf("%d\n",ans!=INF?ans:-1); } return 0; }

最開始寫的bfs程式碼 係數太大 先別吐槽goto 我改完goto 準備交的時候 poj 炸到現在都沒有好orz 等 poj好了 我在交發試一試;

#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <list> 
using namespace std;
typedef long long ll;

const int maxn = 25 ;
const int mod = 1e9+7;
const int INF = 0x3f3f3f3f;
const double PI=acos(-1.0);

int n,m,x;

struct point{
	pair<int,int> P;
	int sp;
	int mp[maxn][maxn];
	bool vis[maxn][maxn];
	void init(){
		memset(mp,0,sizeof(mp));
		memset(vis,0,sizeof(vis));
		sp=0;
	}
	void operator = (point &a){
		this->P=a.P;
		this->sp=a.sp;
		for(int i=0;i<=n;i++) for(int j=0;j<=m;j++) 
			this->mp[i][j]=a.mp[i][j],this->vis[i][j]=a.vis[i][j];
	}
	point(){};
	point(pair<int,int> _p,int _sp,int _mp[maxn][maxn],bool _vis[maxn][maxn]){
		P=_p;sp=_sp;
		for(int i=0;i<=n;i++) for(int j=0;j<=m;j++) 
			mp[i][j]=_mp[i][j],vis[i][j]=_vis[i][j];
	}
	
}st,ed,tmp,tp;

bool check(int x,int y){
	return (x==ed.P.first)&&(y==ed.P.second);
}

int bfs(){
	int res=-1;
	queue<point> que;
	que.push(st);
	int nx,ny;
	while(!que.empty()){
		tp=que.front();que.pop();
		tmp=tp;
		nx=tp.P.first;ny=tp.P.second;
		tmp.vis[nx][ny]=1;
		for(int i=0;i<4;i++){
			nx=tp.P.first;ny=tp.P.second;
			tmp=tp;
		//	cout<<"********"<<nx<<"     "<<ny<<"       "<<tmp.sp<<endl;
			if(i==0){
				if(tmp.mp[nx-1][ny]==1) continue;
				while(nx!=0&&!tmp.mp[nx-1][ny]){
					nx--;
					if(check(nx,ny)){res=tmp.sp+1;goto end;}
				}
				if(nx==0) continue;
				tmp.mp[nx-1][ny]=0;
			}else if(i==1){
				if(tmp.mp[nx+1][ny]==1) continue;
				while(nx!=n&&!tmp.mp[nx+1][ny]){
					nx++;
					if(check(nx,ny)){res=tmp.sp+1;goto end;}
				} 
				if(nx==n) continue;
				tmp.mp[nx+1][ny]=0;
			}else if(i==2){
				if(tmp.mp[nx][ny-1]==1) continue;
				while(ny!=0&&!tmp.mp[nx][ny-1]){
					ny--;
					if(check(nx,ny)){res=tmp.sp+1;goto end;}
				} 
				if(ny==0) continue;
				tmp.mp[nx][ny-1]=0;
			}else{
				if(tmp.mp[nx][ny+1]==1) continue;
				while(ny!=m&&!tmp.mp[nx][ny+1]){
					ny++;
					if(check(nx,ny)){res=tmp.sp+1;goto end;}
				} 
				if(ny==m) continue;
				tmp.mp[nx][ny+1]=0;
			}
		//	cout<<"   "<<nx<<"    "<<ny<<"   "<<tmp.sp<<endl; 
			if(!tmp.vis[nx][ny]&&tmp.sp+1<=10){
				que.push(point(make_pair(nx,ny),tmp.sp+1,tmp.mp,tmp.vis));
			}
		}
	}
	end:
	return res<=10?res:-1;
} 

int main(){
	while(scanf("%d %d",&m,&n)!=EOF&&m+n){
		st.init();
		for(int i=1;i<=n;i++) for(int j=1;j<=m;j++){
			scanf("%d",&x);
			if(x==0) st.mp[i][j]=0;
			else if(x==1) st.mp[i][j]=1;
			else if(x==2){st.mp[i][j]=0; st.P.first=i;st.P.second=j;}
			else{st.mp[i][j]=0;ed.P.first=i;ed.P.second=j;} 
		}
		printf("%d\n",bfs());
	}
	return 0;
}