1 条题解

  • 0
    @ 2025-8-24 22:26:11

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar gaoyangyang
    藿藿真是太可爱啦!!!

    搬运于2025-08-24 22:26:11,当前版本为作者最后更新于2023-09-02 17:23:33,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    会解题的前提是知题意

    翻译

    题目描述(精简版)

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

    输入格式

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

    输出格式

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

    题解

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

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

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

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

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

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

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

    1. ww 等于 bb
    2. wwbb 等于1

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

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

    代码实现:

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

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

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

    代码实现:

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

    接着我们就会发现任何的 bbww 都可以拆成以上两种情况的组合,例如:6677 可以拆成 5555 组合 1122

    下方是矩阵构造的代码:

    //思路是一样的,这里为了方便书写采用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)×2(\min(w,b)-1) \times 2

    部分二的大小为 (max(w,b)min(w,b)+1)×2+1(\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$。

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

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

    
    #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;
    }
     
    
    • 1

    信息

    ID
    6203
    时间
    2000ms
    内存
    256MiB
    难度
    4
    标签
    递交数
    0
    已通过
    0
    上传者