不是什么题都需要算法的
还需要虔诚的心去构造!!!
感觉好久没做过类似的题了,好题啊,拉了solutions中的解答
题意
构造一个h×w 的括号矩阵,使得匹配的行数、列数之和最大。
题解
当h 和w 中有一个是奇数时,构造的方法是显然的。下面仅讨论h 和w 都是偶数的情况。不妨设
h ≤ w。
首先,第一行、最后一列中最多只有一个能够匹配,第一列、最后一行也只有一个能够匹配(考
虑右上角和左下角的括号选取方法),故答案不会超过w+h−2。
当h = 2 时,每一列可以构造一对匹配,这样答案已经到达上界。
当h = 4 时,可以如下构造:
((((((
)))(((
((()))
))))))
这样答案是w+h−3。若存在更优的答案,则必有一个边界能够匹配,不妨设是第一列。这样,就已
经有除第一行以外的两行(右括号开头的行)不匹配了,而第一行和最后一列中至少有一个不匹配,
因此最优解不会超过w+h−3。
当h ≥ 6 时,可以如下构造:
((((((((
()()()()
(()()())
()()()()
(()()())
))))))))
答案是w+h−4。同理可证明不存在更优的方法。
#include <bits/stdc++.h>
using namespace std;
const int maxn=555;
int h,w,ans,type;
char buf[maxn][maxn];
inline void update(const int &x, const int &y) {
if(x > ans) {ans = x; type = y;}
}
int main() {
//freopen("input.txt","r",stdin);
int T;for(scanf("%d", &T);T--;) {
scanf("%d%d", &h, &w);
ans = type = 0;
if(h % 2 == 0) update(w, 1);
if(w % 2 == 0) update(h, 2);
if(h % 2 == 0 && w % 2 == 0) {
update((h + w) / 2, 3);
update(h + w - 4, 4);
if(h == 4) update(w + 1, 5);
if(w == 4) update(h + 1, 6);
}
if(type == 1) {
for(int i = 0; i < h; i++) {
for(int j = 0; j < w; j++) putchar((i & 1) ? ')' : '(');
putchar('\n');
}
} else if(type == 2) {
for(int i = 0; i < h; i++) {
for(int j = 0; j < w; j++) putchar((j & 1) ? ')' : '(');
putchar('\n');
}
} else if(type == 3) {
for(int i = 0; i < h; i++) {
for(int j = 0; j < w; j++) putchar(((i + j) & 1) ? ')' : '(');
putchar('\n');
}
} else if(type == 4) {
for(int i = 0; i < h; i++) {
if(i == 0) {
for(int j = 0; j < w; j++) putchar('(');
}
else if(i == h - 1) {
for(int j = 0; j < w; j++) putchar(')');
}
else {
putchar('(');
for(int j = 1; j < w - 1; j++) putchar(((i + j) & 1) ? ')' : '(');
putchar(')');
}
putchar('\n');
}
} else if(type == 5) {
for(int j = 0; j < w; j++) {
if(j & 1) {
for(int i = 0; i < h; i++) buf[i][j] = (i % 2 == 0) ? '(' : ')';
}
else {
for(int i = 0; i < h / 2; i++) buf[i][j] = '(';
for(int i = h / 2; i < h; i++) buf[i][j] = ')';
}
}
for(int i = 0; i < h; i++) {
for(int j = 0; j < w; j++) putchar(buf[i][j]);
putchar('\n');
}
} else if(type == 6) {
for(int i = 0; i < h; i++) {
if(i & 1) {
for(int j = 0; j < w; j++) putchar(j % 2 == 0 ? '(' : ')');
}
else {
for(int j = 0; j < w / 2; j++) putchar('(');
for(int j = w / 2; j < w; j++) putchar(')');
}
putchar('\n');
}
} else {
for(int i = 0; i < h; i++) {
for(int j = 0; j < w; j++) putchar('(');
putchar('\n');
}
}
}
return 0;
}