正题
题目大意
n∗mn*mn∗m填(((或者)))。求一个方案使得最多的行和列匹配。
解题思路
我们先考虑nnn或mmm为奇数,那么显然奇数的肯定不必配,那么就只需要考虑行或列即可。
若nnn和mmm都为偶数时
我们发现在边边的行列不可能都匹配上,那就让他们无私奉献一下,那么除了这几行就都可以匹配上
Suchas:Such\ as:Such as:
匹配数为n+m−4n+m-4n+m−4
当然我们也可以牺牲一般的行(或列)使得最边边的列(或行)匹配上,
Suchas:Such\ as:Such as:
匹配数为n2+m−1\frac{n}{2}+m-12n+m−1
判断一下哪种更优即可。
codecodecode
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int n,m;
bool v[5001][5001],sw;
int main()
{//freopen("butterfly.in","r",stdin);
// freopen("butterfly.out","w",stdout);scanf("%d%d",&n,&m);if(m&1){int k=1;for(int i=1;i<=n;i++){k^=1;for(int j=1;j<=m;j++)putchar(k?')':'(');putchar('\n');}}else if(n&1){for(int i=1;i<=n;i++){int k=1;for(int j=1;j<=m;j++){k^=1;putchar(k?')':'(');}putchar('\n');}}else{ if(n>m) sw=1,swap(n,m);if(n+m-4<n/2+m-1){for(int i=1;i<=m;i++)v[1][i]=1,v[n][i]=0;int z=0;for(int i=2;i<n;i++){int k=z;z^=1;for(int j=1;j<=m;j++)v[i][j]=(k^=1);}}else{for(int i=1;i<=m;i++)v[1][i]=1,v[n][i]=0;int z=0;for(int i=2;i<n;i++){int k=z;z^=1;v[i][1]=1;v[i][m]=0; for(int j=2;j<m;j++)v[i][j]=(k^=1);}}if(!sw){for(int i=1;i<=n;i++){for(int j=1;j<=m;j++)putchar(v[i][j]?'(':')');putchar('\n');}}else{for(int i=1;i<=m;i++){for(int j=1;j<=n;j++)putchar(v[j][i]?'(':')');putchar('\n');}}}
}