[DFS] Curling 2.0 POJ - 3009

https://vjudge.net/problem/15201/origin

然后图上有不能到的点(墙),起点扔一个球,球只能砸到墙才能停止,但是砸到墙上之后,这个墙就没了,最多可以砸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;
}
全部评论

相关推荐

不愿透露姓名的神秘牛友
11-26 16:06
已编辑
快手电商 后端 23k-35k
点赞 评论 收藏
分享
10-07 20:48
门头沟学院 Java
不敢追175女神:可能是实习上着班想到后面还要回学校给导师做牛马,看着身边都是21-25的年纪,突然emo了了
点赞 评论 收藏
分享
秋招进行到现在终于能写总结了。完全没想到战线会拉这么长,过程会如此狼狈,不过更应该怪自己太菜了。好在所有的运气都用在了最后,也是有个去处。背景:双2本硕科班,无竞赛,本科一段研究所实习,硕士一段大厂暑期实习但无转正。技术栈是C++&nbsp;&amp;&nbsp;Golang,实习是客户端音视频(而且是鸿蒙端开发),简历两个C++项目一个Golang项目。主要投递岗位:后端,cpp软开,游戏服务端,测开,以及一些不拘泥于Java的岗位。从8月起总共投递123家公司,笔试数不清了,约面大约30家。offer/oc/意向:友塔游戏(第一个offer,面试体验很好,就是给钱好少南瑞继保(计算机科班点击就送(限男生),不...
乡土丁真真:佬很厉害,羡慕~虽然我还没有到校招的时候,也想讲一下自己的看法:我觉得不是CPP的问题,佬的背书双2,技术栈加了GO,有两段实习。投了123,面了30.拿到11个offer。这个数据已经很耀眼了。这不也是CPP带来的吗?当然也不止是CPP。至少来说在这个方向努力过的也会有好的结果和选择。同等学历和项目选java就会有更好的吗?我个人持疑问态度。当然CPP在方向选择上确实让人头大,但是我觉得能上岸,至于最后做什么方向,在我看来并不重要。至于CPP特殊,有岗位方向的随机性,java不是不挑方向,只是没得选而已。也希望自己以后校招的时候能offer满满
点赞 评论 收藏
分享
评论
点赞
收藏
分享
牛客网
牛客企业服务