不是什麼題都需要算法的
還需要虔誠的心去構造!!!
感覺好久沒做過類似的題了,好題啊,拉了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;
}