2005. 马蹄铁
尽管奶牛贝茜发现每个平衡括号字符串都很美观,但她特别喜欢被她称为“完全”平衡的括号字符串----一个由 (
构成的字符串后接一个长度相同的 )
构成的字符串。
例如:
(((())))
有一天,当贝茜穿过牛棚时,她发现地面上有一个 N×NN×N 的马蹄铁矩阵。每个马蹄铁的方向都看上去像 (
或 )
。
从矩阵的左上角开始,贝茜希望四处走动以拾起马蹄铁,使得她捡起的马蹄铁按顺序构成的括号字符串是完全平衡的。
请计算她能得到的最长完全平衡括号字符串的长度。
每一步中,贝茜可以沿上下左右四个方向移动。
她只能移动到包含马蹄铁的方格区域内,当她进入该区域时就会拿起那里的马蹄铁,并无法再次回到该位置(因为该位置没有马蹄铁了)。
她首先拿起的是左上角的马蹄铁。
由于她拿起的马蹄铁要形成一个完全平衡的字符串,因此她可能无法将所有马蹄铁都拿起来。
输入格式
第一行包含整数 N。
接下来 N 行,每行包含一个长度为 N 的括号字符串,用来表示括号矩阵。
输出格式
输出她能得到的最长完全平衡括号字符串的长度。
如果无法得到完全平衡括号字符串(例如,左上角马蹄铁形如 )
),则输出 0。
数据范围
2≤N≤5
输入样例:
4
(())
()((
(()(
))))
输出样例:
8
样例解释
贝茜的移动步骤如下:
1())
2)((
345(
876)
代码:
/*
e[N][N] 存储图,如果e[1][1]==’)’提前结束,因为题目要求路径为(((…)))这种格式
vis[N][N]记录走过的路径
一般来说,捡马蹄的方式为先捡 ( ,如果捡了 ) 那么之后就只能捡 ) ,直到 ( 的数目和 ) 的数目一样多。
dfs(x,y,l,r) ==> x,y为当前位置 , L 为已经捡了L个’(‘型马蹄铁,R为已经捡了R个’)‘型马蹄铁
*/
#include <bits/stdc++.h>
using namespace std;
const int N = 8;
int n;
char e[N][N];
bool vis[N][N];
int ne[4][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
int ans = 0;
void dfs(int x, int y, int l, int r)
{
if (l == r) //返回条件
{
ans = max(ans, l + r);
return;
}
for (int i = 0; i < 4; i++)
{
int dx = x + ne[i][0];
int dy = y + ne[i][1];
if (dx < 1 || dx > n || dy < 1 || dy > n)
continue;
if (r > 0 && e[dx][dy] == '(') //剪枝
continue;
if (!vis[dx][dy])
{
vis[dx][dy] = true; //回溯
if (e[dx][dy] == '(')
dfs(dx, dy, l + 1, r);
else
dfs(dx, dy, l, r + 1);
vis[dx][dy] = false;
}
}
}
int main()
{
cin >> n;
for (int i = 1; i <= n; i++)
cin >> e[i] + 1;
if (e[1][1] == ')')
{
cout << "0";
return 0;
}
vis[1][1] = true;
dfs(1, 1, 1, 0);
cout << ans;
return 0;
}