ACM学习感悟——暴力专场B(dfs)

Problem Description

小晴天非常漂亮的后花园,打算以后退休之后在里面种种花,养养草,所以现在小晴天打算为他的后花园围上栅栏。

小晴天的后花园可以看成是一个m*n的矩形,但是其中有一些地方种了树,这些地方都不能安装栅栏,现在小晴天把后花园的平面图告诉你了,请你帮忙设计一个最大的矩形栅栏。

Input

单组数据,第一行包括两个整数m,n(1<=m,n<=500),接下来m行,每行包括n个字符,仅由'x'和'.'组成(ASCII码分别是120与46).

其中‘x’表示这个方格有树木,‘.’表示这个点可以建造栅栏

Output

若可以围成一个闭合栅栏,输出一个整数,表示栅栏能打到的最大周长

否则输出impossible

Sample Input
4 5
.....
.x.x.
.....
.....
2 2
.x
x.
2 5
.....
xxxx.
Sample Output
14
impossible
impossible
Hint

样例一可以绕着整个图一圈,周长为2*(4+3)=14

样例二与三因为有树木的存在,不能建造一个闭合的栅栏。

本题为单文件读写,样例包括三个文件

这道题深搜还是很明显的,但有一点要注意,不能每一步都递归,否则会爆栈,只需要在碰到镜子转弯的时候递归就行了。

AC代码:

//  Created by  CQUWEL			                       
//  Copyright (c) 2015年 CQUWEL. All rights reserved.  

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>           
#include <algorithm>
#include <cctype>
#include <stack>
#include <queue>
#include <map>
#include <string>
#include <set>
#include <vector>
#define INF 0x3f3f3f3f
#define cir(i,a,b)  for (int i=a;i<=b;i++)
#define CIR(j,a,b)  for (int j=a;j>=b;j--)
#define CLR(x) memset(x,0,sizeof(x))
typedef long long  ll;
using namespace std;
int n,m;
int ans,temp;
char g[1010][1010];
int vis[1010][1010];
int dir[4][2]={1,0,0,1,-1,0,0,-1}; 
int mmax(int a, int b)
{
    return a > b ? a : b;
}
void dfs(int dx,int dy,int px,int py)
{
	for (int i=1;;++i)
	{
		int tx=px+i*dx,ty=py+i*dy;
		if (tx<1 || tx>n || ty < 1 || ty > m || g[tx][ty]=='*')
			break;
		if (g[tx][ty]=='E' && !vis[tx][ty])
		{
			temp++;
			vis[tx][ty]=1;
//			printf("g[%d][%d]=%c,%d\n",tx,ty,g[tx][ty],temp);
			continue;
		}
		if (g[tx][ty]=='/' && dx==1)
		{
			dfs(0,-1,tx,ty);break;
		}
		if (g[tx][ty]=='/' && dx==-1)
		{
			dfs(0,1,tx,ty);break;
		}
		if (g[tx][ty]=='/' && dy==1)
		{
			dfs(-1,0,tx,ty);break;
		}
		if (g[tx][ty]=='/' && dy==-1)
		{
			dfs(1,0,tx,ty);break;
		}
		if (g[tx][ty]=='\\' && dx==1)
		{
			dfs(0,1,tx,ty);break;
		}
		if (g[tx][ty]=='\\' && dx==-1)
		{
			dfs(0,-1,tx,ty);break;
		}
		if (g[tx][ty]=='\\' && dy==1)
		{
			dfs(1,0,tx,ty);break;
		}
		if (g[tx][ty]=='\\' && dy==-1)
		{
			dfs(-1,0,tx,ty);break;
		}
	}
	ans=mmax(ans,temp);
}
int main()
{
//	freopen("C:\\Users\\john\\Desktop\\in.txt","r",stdin); 
		cin >> n >> m;
		ans=0;
		int sx,sy;
		for (int i=1;i<=n;i++)
		{
			for (int j=1;j<=m;j++)
			{
				cin >> g[i][j];
				if (g[i][j]=='T')
				{
					sx=i;sy=j;
				}
			}
//			getchar();
		}
		for (int i=0;i<4;i++)
		{
			CLR(vis);
			temp=0;
			dfs(dir[i][0],dir[i][1],sx,sy);
		}
		cout << ans << endl;
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值