题目链接
Parentheses Matrix
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 798 Accepted Submission(s): 323
Special Judge
Problem Description
A parentheses matrix is a matrix where every element is either '(' or ')'. We define the goodness of a parentheses matrix as the number of balanced rows (from left to right) and columns (from up to down). Note that:
- an empty sequence is balanced;
- if A is balanced, then (A) is also balanced;
- if A and B are balanced, then AB is also balanced.
For example, the following parentheses matrix is a 2×4 matrix with goodness 3, because the second row, the second column and the fourth column are balanced:
)()(
()()
Now, give you the width and the height of the matrix, please construct a parentheses matrix with maximum goodness.
Input
The first line of input is a single integer T (1≤T≤50), the number of test cases.
Each test case is a single line of two integers h,w (1≤h,w≤200), the height and the width of the matrix, respectively.
Output
For each test case, display h lines, denoting the parentheses matrix you construct. Each line should contain exactly w characters, and each character should be either '(' or ')'. If multiple solutions exist, you may print any of them.
Sample Input
3
1 1
2 2
2 3
Sample Output
(
()
)(
(((
)))
题意:
给你一个n,m,让你构造一个n*m的矩阵,使得平衡度最高。一行/一列如果括号全部都是平衡(一个'('对称对应一个')')的话,那么总的平衡度就+1
()
)( 该矩阵平衡度就为2,第一行和第一列是平衡的
解析:
这个问题就是分情况讨论。
首先如果n,m都为奇数的话,那么随便输出矩阵,因为平衡度永远为1
如果n,m只有一个为奇数,那么只要按照偶数那一个对应的行/列,保持平衡就可以了,另外一个奇数的列/行不需要考虑,因为永远不可能保持平衡,只要循环在偶数的行/列输出"()"就可以了
如果都为偶数,
有两种方案,一种方案的的平衡度为max(n,m)+min(n,m)/2-1
这种方案是形如
8 6
(()())
(()())
(()())
(()())
()()()
()()()
()()()
()()()
4 4
(())
(())
()()
()()
6 8
((((((((
(((())))
))))((((
(((())))
))))((((
))))))))
注意这里如果是n比较大的话,那么我们就要保证每一行都平衡,按照行来铺
如果m比较大的话,那么我们就要保证每一列都平衡,按照列来铺
上面那种方案在n,m比较小的时候还适用,但一旦n,m变大了之后,min(n,m)/2,这个值也会变大,就会损失更多的行/列
所以第二种的答案就是n+m-4
形如,这个与行列的大小无关
8 10
((((((((()
(()()()())
()()()()()
()()()()()
(()()()())
(()()()())
()()()()()
()))))))))
10 8
((((((()
(()()())
()()()()
()()()()
(()()())
(()()())
()()()()
()()()()
(()()())
()))))))
这种方案的思想就是先把上下左右像围篱笆一样围起来,最外面的2行,2列我们是舍弃的,
那么我们只要在里面填括号,使得剩下的行和列都是平衡的就可以了。
我填着发现一定是有一种方案是可以让里面全都平衡的,并且我还发现了规律。
首先构造一个围好的矩阵8*10(下标从1开始)
((((((((()
( )
( )
( )
( )
( )
( )
()))))))))
然后我们用()()()()填充第一行
((((((((()
(()()()())
( )
( )
( )
( )
( )
()))))))))
填充完后我们发现,在偶数列都是"(("的情况,奇数列都已经平衡,
那么我们就要让偶数列平衡,填充两行“)()()()(”
((((((((()
(()()()())
()()()()()
()()()()()
( )
( )
( )
()))))))))
这样一来我们都在奇数列多了"((",那么我们就用“()()()()”填充下面的两行
((((((((()
(()()()())
()()()()()
()()()()()
(()()()())
(()()()())
( )
()))))))))
这样上面都平衡了,除了刚刚新的两行,在偶数列多了"(("
那么按理还是应该填充两行“)()()()(”,但我们发现只有一行了。
那么我们就只填充一行,这样我们发现就平衡了!
在偶数列,因为最后一行都是")",所以在偶数列我们可以提供两个"))"
那么对于奇数列我么填充一行“)()()()(”会多出来一个“(”,
但是最后一行都是“)”,完全可以填补奇数列多出来的一个“(”!
((((((((()
(()()()())
()()()()()
()()()()()
(()()()())
(()()()())
()()()()()
()))))))))
那么这种方法是不是对所有情况都适用呢?
注意我们这里n,m都是偶数,在排第n-1行的时候,情况一定是要么奇数列多“((”,要么偶数列多"(("
那么对于奇数行多的情况我们只要再排一个"()()()()",加上最后一行奇数列的")",奇数列就平衡了,
对于偶数列多出来的"(",最后一列会平衡掉
同理对于偶数列多"(("的情况在排一个)()()()(就解决了
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int MAXN = 210;
int a[MAXN][MAXN];
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n,m;
scanf("%d%d",&n,&m);
if(n&1||m&1)
{
if(n&1&&m&1)
{
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
a[i][j]=0;
}
else if(n&1)
{
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j+=2)
a[i][j]=0,a[i][j+1]=1;
}
else
{
for(int i=1;i<=m;i++)
for(int j=1;j<=n;j+=2)
a[j][i]=0,a[j+1][i]=1;
}
}
else
{
int ans1=max(n,m)+min(n,m)/2-1;
int ans2=n+m-4;
if(n==2||m==2)
{
if(n==2&&m==2)
{
a[1][1]=0;a[1][2]=1;
a[2][1]=1;a[2][2]=0;
}
else if(n==2)
{
for(int j=1;j<=m;j++)
a[1][j]=0;
for(int j=1;j<=m;j++)
a[2][j]=1;
}
else
{
for(int j=1;j<=n;j++)
a[j][1]=0;
for(int j=1;j<=n;j++)
a[j][2]=1;
}
}
else if(ans1>=ans2)
{
if(n>=m)
{
for(int i=1;i<=n/2;i++)
{
a[i][1]=0;
a[i][m]=1;
for(int j=2;j<m;j+=2)
{
a[i][j]=0;
a[i][j+1]=1;
}
}
for(int i=n/2+1;i<=n;i++)
{
for(int j=1;j<=m;j+=2)
{
a[i][j]=0;
a[i][j+1]=1;
}
}
}
else
{
for(int i=1;i<=m/2;i++)
{
a[1][i]=0;
a[n][i]=1;
for(int j=2;j<n;j+=2)
{
a[j][i]=0;
a[j+1][i]=1;
}
}
for(int i=m/2+1;i<=m;i++)
{
for(int j=1;j<=n;j+=2)
{
a[j][i]=0;
a[j+1][i]=1;
}
}
}
}
else
{
for(int i=1;i<m;i++) a[1][i]=0;
for(int i=1;i<n;i++) a[i][m]=1;
for(int i=2;i<=n;i++) a[i][1]=0;
for(int i=2;i<=m;i++) a[n][i]=1;
int vis,flag;
vis=1;
flag=1;
for(int i=2;i<n;i++)
{
if(vis==2||vis==1&&flag==0)
{
for(int j=2;j<m;j+=2)
a[i][j]=1,a[i][j+1]=0;
vis--;
flag=0;
}
else if(vis==1&&flag||vis==0)
{
for(int j=2;j<m;j+=2)
a[i][j]=0,a[i][j+1]=1;
vis++;
flag=1;
}
}
}
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(a[i][j]) printf(")");
else printf("(");
}
printf("\n");
}
}
return 0;
}