马蹄印
题目
虽然当奶牛贝里斯找到平衡序列后很高兴了,但是他现在对序列提出了一个更高的要求,就是要求每个序列中必须是先一定数量的左括号然后是与左括号相同数量的右括号。例如:(((()))),就是一个完美的平衡序列。
当贝里斯某天在农场上走的时候,他在地上发现了马蹄印,这个农场是一个N*N的方格,每个小方格中都有一个马蹄印。贝里斯希望从方格的最左上角的地方开始出发,然后每次可以向上或者向下或者向左或者向右移动一步,使得他走过的每个小方格中的马蹄印能够组成一个完美的平衡序列。当然了,贝里斯不能重复经过任何小方格。
请帮助贝里斯在这个N*N的方格中找出长度最长的完美序列的长度。
输入
第一行一个正整数N,表示农场的大小。
接下来N行,每行N个字符,表示N*N的方格上马蹄印的分布情况。
输出
只有一行一个整数,表示最长的完美序列的长度,如果不存在这样的完美序列(例如起始位置就是右括号),则输出0。
输入样例
4
(())
()((
(()(
))))
输出样例
8
样例说明
样例中,奶牛的行走序列是这样的:
1())
2)((
345(
876)
数据范围
2<=N<=5
思路
这道题就是一道搜索题。
你就一直搜索下去,遇到左括号数量与右括号数量相同的情况时就对答案取一个max值,以求出最长的完美序列。
代码
#include<cstdio>
#include<iostream>
using namespace std;
int n,answer,xx[4]={1,0,-1,0},yy[4]={0,1,0,-1};
char a[6][6];
bool f[6][6];
bool check(int xxx,int yyy)//判断是否能走
{
if (xxx>0&&xxx<=n&&yyy>0&&yyy<=n&&!f[xxx][yyy]) return 1;
return 0;
}
void dfs(int x,int y,int zuo,int you)
{
if (zuo==you)//判断是否已经形成一个完美序列
{
answer=max(zuo+you,answer);//求出最长的完美序列
return;
}
for (int i=0;i<=3;i++)//四种方向
if (check(x+xx[i],y+yy[i]))//如果可以走
{
f[x+xx[i]][y+yy[i]]=1;
if (a[x+xx[i]][y+yy[i]]=='('&&!you)
dfs(x+xx[i],y+yy[i],zuo+1,you);//为左括号的情况
else if (a[x+xx[i]][y+yy[i]]==')')
dfs(x+xx[i],y+yy[i],zuo,you+1);//为右括号的情况
f[x+xx[i]][y+yy[i]]=0;
}
}
int main()
{
scanf("%d",&n);//读入
getchar();//处理换行符
for (int i=1;i<=n;i++)
{
for (int j=1;j<=n;j++)
a[i][j]=getchar();//读入
getchar();//处理换行符
}
f[1][1]=1;//初始化
if (a[1][1]==')') {printf("0");return 0;}//如果一开始就没得走则输出0
dfs(1,1,1,0);//dfs
printf("%d",answer);//输出
return 0;
}