构造一个n*m的‘(’,‘)’矩阵,使得矩阵的完全匹配行数和完全匹配列数之和最大。
完全匹配:如()(),(())。
思路:
分类讨论,找规律。
如果n和m都为奇数,要求的值一定为0,随便构造就可以了。
如果n和m中只有一个为偶数,要求的值即为奇数。只可能在所有行或者所有列中实现括号匹配。
如果n和m都为偶数,考虑的情况比较多。
假设n<=m。构造时,第一行和最后一列中最多只有一个能够匹配。第一列最后一行也只有一个能匹配,答案最多为w+h-2。
当 h = 2 时,每一列可以构造一对匹配,这样答案已经到达上界。
当 h = 4 时,可以如下构造:
((((((
)))(((
((()))
))))))
这样答案是 w+ h- 3。若存在更优的答案,则必有一个边界能够匹配,不妨设是第一列。这样,就已
经有除第一行以外的两行(右括号开头的行)不匹配了,而第一行和最后一列中至少有一个不匹配,
因此最优解不会超过 w+ h- 3。
当 h ≥ 6 时,可以如下构造:
((((((((
()()()()
(()()())
()()()()
(()()())
))))))))
答案是 w+ h- 4。
#include<bits/stdc++.h>
#define ll long long
using namespace std;
char a[505][505];
int main()
{
int t,i,j,n,m;
cin>>t;
while(t--)
{
cin>>n>>m;
if((n&1)&&(m&1))
{
for(i=0;i<n;i++)
{
for(j=0;j<m;j++)
a[i][j]='(';
}
}
else if(n&1)
{
for(i=0;i<n;i++)
{
for(j=0;j<m;j++)
{
if(j%2)
a[i][j]=')';
else
a[i][j]='(';
}
}
}
else if(m&1)
{
for(i=0;i<m;i++)
{
for(j=0;j<n;j++)
{
if(j%2)
a[j][i]=')';
else
a[j][i]='(';
}
}
}
else
{
if(n==2)
{
for(int i=0;i<m;i++)
{
a[0][i]='(';
a[1][i]=')';
}
}
else if(m==2)
{
for(int i=0;i<n;i++)
{
a[i][0]='(';
a[i][1]=')';
}
}
else if(n==4)
{
for(i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
if(i==0) a[i][j]='(';
else if(i==n-1) a[i][j]=')';
else if((i&1)&&(j<m/2)) a[i][j]=')';
else if(i&1) a[i][j]='(';
else if(j<m/2) a[i][j]='(';
else a[i][j]=')';
}
}
}
else if(m==4)
{
for(i=0;i<m;i++)
{
for(int j=0;j<n;j++)
{
if(i==0) a[j][i]='(';
else if(i==m-1) a[j][i]=')';
else if((i&1)&&(j<n/2)) a[j][i]=')';
else if(i&1) a[j][i]='(';
else if(j<n/2) a[j][i]='(';
else a[j][i]=')';
}
}
}
else if(n>=m)
{
for(i=0;i<m;i++)
{
for(int j=0;j<n;j++)
{
if(i==0) a[j][i]='(';
else if(i==m-1) a[j][i]=')';
else if((i&1)&&(j&1)) a[j][i]=')';
else if(i&1) a[j][i]='(';
else if(j==0) a[j][i]='(';
else if(j==n-1) a[j][i]=')';
else if(j&1) a[j][i]='(';
else a[j][i]=')';
}
}
}
else
{
for(i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
if(i==0) a[i][j]='(';
else if(i==n-1) a[i][j]=')';
else if((i&1)&&(j&1)) a[i][j]=')';
else if(i&1) a[i][j]='(';
else if(j==0) a[i][j]='(';
else if(j==m-1) a[i][j]=')';
else if(j&1) a[i][j]='(';
else a[i][j]=')';
}
}
}
}
for(i=0;i<n;i++)
{
for(j=0;j<m;j++)
cout<<a[i][j];
cout<<endl;
}
}
return 0;
}