>Description
奶牛贝里斯对序列提出了一个更高的要求,就是要求每个序列中必须是先一定数量的左括号然后是与左括号相同数量的右括号。例如:(((()))),就是一个完美的平衡序列。
这个农场是一个NN的方格,每个小方格中都有一个马蹄印。贝里斯希望从方格的最左上角的地方开始出发,然后每次可以向上或者向下或者向左或者向右移动一步,使得他走过的每个小方格中的马蹄印能够组成一个完美的平衡序列。不能重复经过任何小方格。请帮助贝里斯在这个NN的方格中找出长度最长的完美序列的长度。
>Input
第一行一个正整数N,表示农场的大小。
接下来N行,每行N个字符,表示N*N的方格上马蹄印的分布情况。
>Output
只有一行一个整数,表示最长的完美序列的长度,如果不存在这样的完美序列(例如起始位置就是右括号),则输出0。
>Sample Input
4
(())
()((
(()(
))))
>Sample Output
8
数据范围:2<=N<=5。
>解题思路
深搜。
>代码
#include<iostream>
#include<cstdio>
using namespace std;
const int xx[4]={-1,0,0,1};
const int yy[4]={0,-1,1,0};
int n,ans;
char a[6][6];
string s;
bool yd[6][6];
void ooo(int x,int y,int l,int r)//分别记录坐标,左括号和右括号的数量
{
yd[x][y]=1; //标记走过
if(l==r) //如果平衡
{
ans=max(ans,l+r);
yd[x][y]=0; //回溯
return;
}
if(l<r) return; //如果已经不平衡了
for(int i=0;i<4;i++)
{
if(x+xx[i]>n||x+xx[i]<1||y+yy[i]>n||y+yy[i]<1) continue; //判断越界
if(yd[x+xx[i]][y+yy[i]]) continue; //判断是否走过
if(a[x+xx[i]][y+yy[i]]==')') ooo(x+xx[i],y+yy[i],l,r+1);
else if(r==0) ooo(x+xx[i],y+yy[i],l+1,r); //如果已经开始记录右括号的话就不能再记录左括号了
}
yd[x][y]=0; //回溯
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
cin>>s;
for(int j=1;j<=n;j++)
a[i][j]=s[j-1];
}
yd[1][1]=1; //yd[i][j]标记(i,j)是否走过
if(a[1][1]=='(')
{
ooo(1,1,1,0); printf("%d",ans);
}
else printf("0"); //如果开始就是右括号的话就组成不了平衡序列
return 0;
}