HDU 6400 Parentheses Matrix (矩阵构造)

题目链接

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;
}

猜你喜欢

转载自blog.csdn.net/qq_37025443/article/details/81772106