2020寒假【gmoj1747】【马蹄印】【DFS】

题目描述

虽然当奶牛贝里斯找到平衡序列后很高兴了,但是他现在对序列提出了一个更高的要求,就是要求每个序列中必须是先一定数量的左括号然后是与左括号相同数量的右括号。例如:(((()))),就是一个完美的平衡序列。

当贝里斯某天在农场上走的时候,他在地上发现了马蹄印,这个农场是一个N* N的方格,每个小方格中都有一个马蹄印。贝里斯希望从方格的最左上角的地方开始出发,然后每次可以向上或者向下或者向左或者向右移动一步,使得他走过的每个小方格中的马蹄印能够组成一个完美的平衡序列。当然了,贝里斯不能重复经过任何小方格。
请帮助贝里斯在这个N*N的方格中找出长度最长的完美序列的长度。

输入

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

输出

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

样例输入

4 
(()) 
()(( 
(()( 
))))

样例输出

8

分析

这题可以设l,r分别表示左括号和右括号的个数,这两个如果相等,那么就可以加起来记录长度。两边分别dfs找一下,注意判断条件(详见注释),每次max统计最大值。

上代码!

#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
using namespace std;
int n,ans,p[10][10];
char a[10][10];
const int dx[5]={0,0,-1,0,1};
const int dy[5]={0,1,0,-1,0};
void dfs(int x,int y,int l,int r)
{
	if(l==r)//平衡 
	{
		ans=max(ans,l+r);//记录最大值 
		return;
	}
	for(int i=1;i<=4;i++)
	{ 
	    int xx=x+dx[i];
		int yy=y+dy[i]; 
	    if(xx>0&&xx<=n&&yy>0&&yy<=n&&!p[xx][yy])
	    {
	    	p[xx][yy]=1;//访问记录 
	    	if(a[xx][yy]=='('&&r==0)//要没有走过右括号才能走左括号 
	    	{
	    		dfs(xx,yy,l+1,r);
			}
	    	if(a[xx][yy]==')')
	    	{
	    		dfs(xx,yy,l,r+1);
			}
	    	p[xx][yy]=0;//清零,回溯 
	    }
	}    
}
int main()
{
	freopen("hshoe.in","r",stdin);
	freopen("hshoe.out","w",stdout); 
	cin>>n;
	getchar();//防止输入错误 
	for(int i=1;i<=n;i++)
	{
	  	for(int j=1;j<=n;j++)
	  	{
	  	    cin>>a[i][j];//读入 
		}
	}
	p[1][1]=1;//初值
	if (a[1][1]==')') cout<<0;
	else 
	{
		dfs(1,1,1,0);
		cout<<ans;
	}
	fclose(stdin);
	fclose(stdout);
	return 0; 
}
发布了63 篇原创文章 · 获赞 61 · 访问量 5443

猜你喜欢

转载自blog.csdn.net/dglyr/article/details/104331133
今日推荐