题目:
虽然当奶牛贝里斯找到平衡序列后很高兴了,但是他现在对序列提出了一个更高的要求,就是要求每个序列中必须是先一定数量的左括号然后是与左括号相同数量的右括号。例如:(((()))),就是一个完美的平衡序列。
当贝里斯某天在农场上走的时候,他在地上发现了马蹄印,这个农场是一个N*N的方格,每个小方格中都有一个马蹄印。贝里斯希望从方格的最左上角的地方开始出发,然后每次可以向上或者向下或者向左或者向右移动一步,使得他走过的每个小方格中的马蹄印能够组成一个完美的平衡序列。当然了,贝里斯不能重复经过任何小方格。
请帮助贝里斯在这个
N
∗
N
N*N
N∗N的方格中找出长度最长的完美序列的长度。
输入:
第一行一个正整数N,表示农场的大小。
接下来N行,每行N个字符,表示N*N的方格上马蹄印的分布情况。
输出:
只有一行一个整数,表示最长的完美序列的长度,如果不存在这样的完美序列(例如起始位置就是右括号),则输出0。
样例输入:
4
(())
()((
(()(
))))
样例输出:
8
思路:
输出“0”30分,我也是服了。。。
n<=5直接dfs搜,如果是左括号就right+1,如果是有括号就left+1
代码:
#include<cstdio>
#include<iostream>
using namespace std;
int s[1000][1000];
char f[10][10];//左右括号矩阵
const int xx[15]={-1,0,0,1};//四个方向
const int yy[15]={0,-1,1,0};
int n,sum;
string c;
bool check(int x,int y)//边界
{
if(x>0&&y>0&&x<=n&&y<=n&&!s[x][y]) return 1;
return 0;
}
void dfs(int x,int y,int lift,int right)
{
if(lift==right)//如果左右平衡
{
sum=max(sum,lift+right);//搜完了
return;
}
for(int i=0;i<4;i++)
{
if(check(x+xx[i],y+yy[i]))//判断出界
{
s[x+xx[i]][y+yy[i]]=true;//先标记
if(f[x+xx[i]][y+yy[i]]=='('&&!right)//左括号
dfs(x+xx[i],y+yy[i],lift+1,right);//搜
if(f[x+xx[i]][y+yy[i]]==')')//右括号
dfs(x+xx[i],y+yy[i],lift,right+1);//搜
s[x+xx[i]][y+yy[i]]=false;//回溯
}
}
}
int main()
{
scanf("%d",&n);
for(int i=1;i<= n;i++)
{
cin>>c;
for(int j=1;j<=n;j++)
f[i][j]=c[j-1];//输入
}
s[1][1]=1;
if(f[1][1]==')')printf("0");//如果第一个是右括号就直接输出0
else {dfs(1,1,1,0);printf("%d",sum);}//搜+输出
return 0;
}