题解 P6368 【 [COCI2006-2007#6] MAGIJA】

· · 题解

此题难点在于复制,难度不大。

本人一开始写的时候彻底弄错了,果然是蒟蒻

根据题意 Al'Dimi Kartimi 将会先绘制左上角的图像,由 # 和 . 组成,然后再在这一部分的右侧,正下方,以及右下方进行镜像复制

必要的变量

本题我会使用 a[r][m] b[2 \times r + 5][2 \times m + 5] 来对于需要输入和输出的图形进行储存。

关于镜像复制

我们对于复制的第一想法就是平移复制(包括笔者)。

关于平移复制如下:

##.. --> ##..##..

没错,这就是平移复制,这里就要说到读题的重要性了。因为题目中提到的是:将图形沿着矩形的垂直与水平方向的中垂线绘制右上方以及各个位置的图形。

所以:平移复制(×) ——> 镜像复制(√)

那么根据题意,我们以第一个样例为例子来进行分析。

输入的 r m 2、2,以及输入的图形如下:

#.
.#

那么也就是说我们如果进行镜像复制就会得到:

#..#
.##.
.##.
#..#

这很显然才是题目要求的正解。

关于如何进行复制

我们可以对于右边的部分进行分析,即: { (1,3) 和 (1,2) } { (1,1) 和 (1,4) } 这两组数据来进行分析。

我们可以发现的是同一排的被复制的以及原来位置的 y 位置的相加之和等于 2 \times m + 1

这样子我们可以得到一个对于右半部分进行复制的式子: b[ x ][ y ]=a[ x ][ 2 \times m - y + 1 ]

得到了上一个式子之后,我们可以故技重施再找出将上下的复制的式子: b[ x ][ y ]=b[ 2 \times r + 1 - x ][ y ]

在得到了这两个式子之后,本题已经清晰明了了。

最后一步

所以我们在对于 a 数组进行复制为 b 数组后,只要将 Al'Dimi Kartimi 所故意犯的错误添加上去即可。

思路就是判断输入的 x y 位置上的字符是 # 还是 . 即可。

3. 判断代码如下:

if(b[x][y]=='#') b[x][y]='.';
else b[x][y]='#';

所以,本题已经 “ AC ” 了,来看代码吧!

Code

#include<bits/stdc++.h>
using namespace std;

char a[105][105];
char b[105][105];

int main () {
    int l,r;
    int x,y;
    scanf("%d%d",&l,&r);
    for(int i=1;i<=l;i++)
        for(int j=1;j<=r;j++){
            cin>>a[i][j];//一个一个输入更便于判断,如果用scanf可能会搞错下标,所以还是cin大法好。
            b[i][j]=a[i][j];//将b数组变成与a数组相同的形式。
        }
    cin>>x>>y;
    for(int i=1;i<=l;i++)
        for(int j=r+1;j<=2*r;j++){
            b[i][j]=a[i][2*r-j+1];//沿竖直方向进行复制。
        }
    for(int i=l+1;i<=2*l;i++)
        for(int j=1;j<=2*r;j++){
            b[i][j]=b[2*l+1-i][j];//沿着水平方向进行复制。
        }
    if(b[x][y]=='#') b[x][y]='.';
    else b[x][y]='#';//判断且犯小错误。

    for(int i=1;i<=2*l;i++){
        for(int j=1;j<=2*r;j++){
            cout<<b[i][j];
        }
        cout<<endl;//输出一行后的换行。
    }

    return 0;
}

后记

关于这一题,其实难度不大,对于字符串不是很熟练的小伙伴可以来试一试哦~~

蒟蒻的第二篇题解,管理大大求过嘿嘿。