【DFS】马蹄印(Horseshoes)

题目描述

虽然当奶牛贝里斯找到平衡序列后很高兴了,但是他现在对序列提出了一个更高的要求,就是要求每个序列中必须是先一定数量的左括号然后是与左括号相同数量的右括号。例如:(((()))),就是一个完美的平衡序列。
当贝里斯某天在农场上走的时候,他在地上发现了马蹄印,这个农场是一个N*N的方格,每个小方格中都有一个马蹄印。贝里斯希望从方格的最左上角的地方开始出发,然后每次可以向上或者向下或者向左或者向右移动一步,使得他走过的每个小方格中的马蹄印能够组成一个完美的平衡序列。当然了,贝里斯不能重复经过任何小方格。

问题描述:

请帮助贝里斯在这个N*N的方格中找出长度最长的完美序列的长度。

输入

第一行一个正整数N,表示农场的大小。
接下来N行,每行N个字符,表示N*N的方格上马蹄印的分布情况。

输出

只有一行一个整数,表示最长的完美序列的长度,如果不存在这样的完美序列(例如起始位置就是右括号),则输出0。

输入样例
4 
(()) 
()(( 
(()( 
)))) 
输出样例
8

说明

数据范围:2<=N<=5。
说明:样例中,奶牛的行走序列是这样的:
1())
2)((
345(
876)

思路

DFS搜

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
const int dx[4]={1,0,-1,0};
const int dy[4]={0,1,0,-1};
int F[25][25];
int Ans,n,m;
char s;
bool Check(int x,int y,int r,int c)
{
	if(x<1 || x>n || y<1 || y>n)return 0;
	if(F[x][y]==1 && r+1>(n*n+1)/2)return 0;
	if(F[x][y]==0 && r<c+1)return 0;
	if(F[x][y]==1 && c)return 0;//一堆优化
	if(F[x][y]==-1)return 0; 
	return 1;
}
void Dfs(int x,int y,int r,int c)
{
	if(r==c)
	{
		Ans=max(Ans,r+c);
		return;
	}
	for(int i=0;i<=3;++i)
		if(Check(x+dx[i],y+dy[i],r,c))
		{
			int m=F[x+dx[i]][y+dy[i]];
			F[x+dx[i]][y+dy[i]]=-1;
			if(m==1)r++;else if(m==0)c++;
			Dfs(x+dx[i],y+dy[i],r,c);
			F[x+dx[i]][y+dy[i]]=m;
			if(m==1)r--;else if(m==0)c--;
		}
}
int main()
{
	scanf("%d\n",&n);
	for(int i=1;i<=n;++i)
	{
		for(int j=1;j<=n;++j)
		{
			s=getchar();
			if(s=='(')F[i][j]=1;
			else if(s==')')F[i][j]=0;
		}
		while(s!='\n')s=getchar();
	}
	if(F[1][1])//如果(1,1)为右括号就不用做了
	{
		F[1][1]=-1; 
		Dfs(1,1,1,0);
	}
	printf("%d",Ans);
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值