P7049 [NWRRC2015] Black and White

· · 题解

会解题的前提是知题意

翻译

题目描述(精简版)

给定正整数 b,w 请你构造出一个黑白矩阵,使得矩阵内恰有 b 个黑色连通块和 w 个白色连通块。

输入格式

输入仅有一行,包含 b,w 即黑色和白色区域的数量。(1 \le b , w \le 1000

输出格式

输出的第一行包含两个整数 r,c,表示你构造出的矩阵的行数和列数。接下来是一个 r\times c 的矩阵,表示你构造出的黑白矩阵。其中 @ 代表黑色,. 代表白色。

题解

看到这道题我们的第一反应应该是将问题简单化。在这里我们将问题分为两个部分:

  1. 构建矩阵
  2. 输出规格

首先我们先考虑构建矩阵,我们不妨先不考虑黑和白,先想如何构建一个单一符号矩阵,如下:

@@
@@
@@
@@
@@

//这是一个有@组成的2*5矩阵

想必大家都会,并且在这里还可少考虑一个“列”的因素(因为矩阵大小自定,所以满足题目条件只需调整“行”而不用考虑“列”),在这里我用 2 作为列:

for (int i=0;i<n;i++)
{
  cout<<"@@"<<endl;
}
//n为行数

接下来,我们考虑符号,这里要考虑两种情况:

  1. w$ 等于 $b

我们先考虑第一种,w 等于 b,我们可以轻易构出下方矩阵。

//b=2,w=2
@@
..
@@
..
//————华丽分割线————
..
@@
..
@@

代码实现:

for (int i=0;i<(w+b)/2;i++)
{
  cout<<"@@"<<endl;
  cout<<".."<<endl;
}
//n为行数

接下来是第二种 wb 等于1,我们可以轻易构出下方矩阵。

//b=1,w=3
@@
.@
@@
.@
@@
.@
@@
//反之

代码实现:

for (int i=0;i<w;i++)
{
  cout<<"@@"<<endl;
  cout<<".@"<<endl;
 }cout<<"@@";

接着我们就会发现任何的 bw 都可以拆成以上两种情况的组合,例如:67 可以拆成 55 组合 12

下方是矩阵构造的代码:

//思路是一样的,这里为了方便书写采用while循环
while (w!=0 or b!=0)
    {
        if (b>w)
        {
            while (w>1 and b>1)
            {
                cout<<"@@"<<endl;
                b--;
                cout<<".."<<endl;
                w--;
            }
            if (w==1)
            {
                w--;
                cout<<"@@"<<endl;
                while (b!=0)
                {
                    cout<<".@"<<endl;
                    cout<<"@@"<<endl;
                    b--;
                }
            }       
        }
        else
        {
            while (w>1 and b>1)
            {
                cout<<".."<<endl;
                w--;
                cout<<"@@"<<endl;
                b--;
            }
            if (b==1)
            {
                b--;
                cout<<".."<<endl;
                while (w!=0)
                {
                    cout<<"@."<<endl;
                    cout<<".."<<endl;
                    w--;
                }
            }           
        }
    }

接下来我们考虑第二块:输出规格。

同上将矩阵分成两个部分,就可以得出:

部分一的大小为 (\min(w,b)-1) \times 2

部分二的大小为 (\max(w,b) - \min(w,b) + 1) \times 2+1

我们再相加,就可得出 (\min(w,b)-1) \times 2 + (\max(w,b) - \min(w,b) + 1) \times 2+1

”行“我们就解决了,我们再将列人为的定为 2(其他也可以,只要对应矩阵就好)。

至此这道题我们就解决了,下面上代码!!!


#include<bits/stdc++.h>
using namespace std;
int main()
{
    int w,b;
    cin>>w>>b;
    cout<<(min(w,b)-1)*2+1+(max(w,b)-min(w,b)+1)*2<<" "<<2<<endl;

    while (w!=0 or b!=0)
    {
        if (b>w)
        {
            while (w>1 and b>1)
            {
                cout<<"@@"<<endl;
                b--;
                cout<<".."<<endl;
                w--;
            }
            if (w==1)
            {
                w--;
                cout<<"@@"<<endl;
                while (b!=0)
                {
                    cout<<".@"<<endl;
                    cout<<"@@"<<endl;
                    b--;
                }
            }       
        }
        else
        {
            while (w>1 and b>1)
            {
                cout<<".."<<endl;
                w--;
                cout<<"@@"<<endl;
                b--;
            }
            if (b==1)
            {
                b--;
                cout<<".."<<endl;
                while (w!=0)
                {
                    cout<<"@."<<endl;
                    cout<<".."<<endl;
                    w--;
                }
            }           
        }
    }
    return 0;
}