AT_utpc2011_4 停止問題 题解

题目

思路

dfs。
按照题意下一个又臭又长的dfs。因为这个题目某个点可以重复走,所以标记状态的时候得加上当前走的方向和当前存储的数字。
为了防止进入死循环之中我们可以记录一下经过某个点的次数如果经过太多次就说明进入了死循环,那就不能再进去了。

代码

#include<bits/stdc++.h>
#include<cstring>
#include<queue>
#include<set>
#include<stack>
#include<vector>
#include<map>
#define ll long long
#define lhs printf("\n");
using namespace std;
const int N=1e5+10;
const int M=2024;
const int inf=0x3f3f3f3f;
int n,m;
char a[114][114];
int ddx[]={0,0,-1,1};
int ddy[]={1,-1,0,0};
int v[30][30][5][20],vis[30][30];
/*
v标记状态
vis记录走过的次数
*/
int k;
int flag;
void dfs(int x,int y,int f,int num)//f是方向	
{
	int flag=0;
	int dx,dy,nf=f;
	if(a[x][y]=='<')
	{
		nf=2;
	}
	else if(a[x][y]=='>')
	{
		nf=1;
	}
	else if(a[x][y]=='^')
	{
		nf=3;
	}
	else if(a[x][y]=='v')
	{
		nf=4;
	}
	else if(a[x][y]=='_')
	{
		if(num==0)
		{
			nf=1;
		}
		else 
		{
			nf=2;
		}
	}
	else if(a[x][y]=='|')
	{
		if(num==0)
		{
			nf=4;
		}
		else
		{
			nf=3;
		}
	}
	else if(a[x][y]=='?')
	{
		flag=1;
	}
	else if(a[x][y]=='@')
	{
		k=1;
		cout<<"YES\n";
		exit(0);
	}
	else if('0'<=a[x][y] and a[x][y]<='9')
	{
		num=int(a[x][y])-48;
	}
	else if(a[x][y]=='+')
	{
		num++;
		if(num==16)
		{
			num=0;
		}
	}
	else if(a[x][y]=='-')
	{
		num--;
		if(num==-1)
		{
			num=15;
		}
	}
	if(nf==1)//右 
	{
		dx=0;
		dy=1;
	}
	else if(nf==2)//左 
	{
		dx=0;
		dy=-1;
	}
	else if(nf==3)//上 
	{
		dx=-1;
		dy=0;
	}
	else if(nf==4)//下 
	{
		dx=1;
		dy=0;
	}
//	cout<<nf<<"\n";
	int nx=x+dx;
	int ny=y+dy;
	if(flag)
	{
		for(int i=0;i<4;i++)
		{
			int nx=x+ddx[i];
			int ny=y+ddy[i];
			if(nx<1)
			{
				nx=n;
			}
			if(nx>n) 
			{
				nx=1;
			} 
			if(ny<1)
			{
				ny=m;
			}
			if(ny>m)
			{
				ny=1;
			}
			if(v[nx][ny][i+1][num]==0 and vis[nx][ny]<=1000)
			{
				vis[nx][ny]++; 
				v[nx][ny][i+1][num]=1;
				dfs(nx,ny,i+1,num);
				v[nx][ny][i+1][num]=0;
//				vis[nx][ny]--;
			}
		}
	}
	else
	{
		if(nx<1)
		{
			nx=n;
		}
		if(nx>n) 
		{
			nx=1;
		} 
		if(ny<1)
		{
			ny=m;
		}
		if(ny>m)
		{
			ny=1;
		}
		if(v[nx][ny][nf][num]==0 and vis[nx][ny]<=1000)
		{
			vis[nx][ny]++;
			v[nx][ny][nf][num]=1;
			dfs(nx,ny,nf,num);
			v[nx][ny][nf][num]=0;
//			vis[nx][ny]--;
		}
	}
}
int main()
{
	cin>>n>>m;
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=m;j++)
		{
			cin>>a[i][j];
			if(a[i][j]=='@')
			{
				flag=1;
			}
		}
	}
	if(!flag)//没有终点就直接不用搜了
	{
		cout<<"NO\n";
		return 0;
	}
	dfs(1,1,1,0);
	if(!k)
	{
		cout<<"NO\n";
	}
	return 0;
}
/*
2 6
5>--v.
.^--_@

2 6
8^..<.
->..|.

3 3
2v@
v<?
>.^

5 5
3v_.@
v<??? 
>????
|||||
.....

5 5
?????
?????
?????
?????
?????

5 6
10--+?
|-__35
..^++?
<<@>?-
--v+--
几组测试数据
*/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值