P9908 [COCI 2023/2024 #2] Pahuljice题解

· · 题解

P9908 [COCI 2023/2024 #2] Pahuljice

我们无论解什么题都要贯彻一个思想:“解其题,必先知其题;何解题,必为简其题。”

其实就是先读题,再把问题简化成多个简单的小问题,然后一一解决,最后问题得解。

首先我们来完成第一步“知其题”

审题又分为 3 步走

  1. 区分有用的信息和没用的信息

从题目中我们可以简单的得出“有用的信息”。

即“什么样的图形是雪花”(下方是一个大小为 x 的雪花的要求,同题目描述)。

//雪花大小为2:
/*
\.|./
.\|/.
--+--
./|\.
/.|.\
*/

以及“我们要找的目标是什么”——最大雪花的大小

  1. 将有用的信息联系起来

通过上面的审题我们了解到了两个关键点即“条件”和“目标”。我们要从其给出的条件来达成目标。这时我们可以列出以下大概思路:首先找到所有雪花,再算出每朵雪花的大小,最后找出最大的一朵,输出得解

  1. 有用的信息转化为伪代码语言

看完了题,我们要开始准备代码了。依题意可以看出在题中怎样是一朵雪花。我们这里用代码来表示一下:

假定雪花 a中心 + 的索引为 [i][j]

那么其 [i+n][j][i-n][j] 都必须是 |

[i][j+n][i][j-n] 都必须是 -

[i+n][j+n][i-n][j-n] 都必须是 /

[i-n][j+n][i+n][j-n] 都必须是 \

如果(0\le p\le np 为其间任意值都成立那么 n 就是这朵雪花的大小。是不是感觉还有点模糊?没关系我们往下看。

接下来我们完成第二步“简其题”

刚刚我们阅读了题目,也写了“伪代码”。我们就要化简题目了。怎么简呢?从判断雪花大小的地方减。阅读规则我们不难发现每个雪花都有一个特点就是有一个 +,我们可以以这个 +切入点化简题目。

我们先在“图”中寻找 +,如果找到了就立即开始计算其大小。怎么算呢?先前不是提到了吗?找一个 p 来帮忙,来帮助我们确定 n 的值也就是大小了。p 作为偏移量一开始为 1 随后慢慢加大直到判断为这不再是一朵雪花为止,而此时雪花的大小也就确定了,也就是 p-1,在比较其是否最大的雪花就可以了。上代码:

if (a[i][j]=='+')//判断是否为雪花中心点
    {
    int p=1;//定义偏移量p
    while(1)
    {
        if (i+p>=m or i-p<0 or j+p>=n or j-p<0)break;
        if (a[i+p][j]!='|' or a[i-p][j]!='|')break;
        if (a[i][j+p]!='-' or a[i][j-p]!='-')break;
        if (a[i+p][j+p]!=char(92) or a[i-p][j-p]!=char(92))break;
      //由于“\”有特殊意义,所以常规方法不方便书写,这里用ASCLL码表示
        if (a[i-p][j+p]!='/' or a[i+p][j-p]!='/')break;
        max_=max(p,max_);//判断这朵雪花是不是最大的
        p++;
    }

}

别走还没结束!

最后我们完成最后一步“解其题”

化简完了就开始解题,然后我们就会发现这是最简单的一步。

先初始化,再写输入,然后遍历图表,判断大小,比较大小,输出。这就结束了,自此,世界安静了。

然后我们遵循“Talk is cheap,show me the code.”的原则,我们上代码:

#include<bits/stdc++.h>
using namespace std;
int main()
{
    char a[51][51];
    int m,n;
    cin>>m>>n;
    int max_=0;
    for (int i=0;i<m;i++)
    {
        for (int j=0;j<n;j++)
        {
            cin>>a[i][j];
        }
    }//初始化+输入

    for (int i=0;i<m;i++)
    {
        for (int j=0;j<n;j++)
        {
            if (a[i][j]=='+')//判断是否为雪花中心点
            {
                int p=1;//定义偏移量p
                while(1)
                {
                    //if (p==0){p++;continue;}

                    if (i+p>=m or i-p<0 or j+p>=n or j-p<0)break;
                    if (a[i+p][j]!='|' or a[i-p][j]!='|')break;
                    if (a[i][j+p]!='-' or a[i][j-p]!='-')break;
                    if (a[i+p][j+p]!=char(92) or a[i-p][j-p]!=char(92))break;//由于“\”有特殊意义,所以常规方法不方便书写,这里用ASCLL码表示
                    if (a[i-p][j+p]!='/' or a[i+p][j-p]!='/')break;
                    max_=max(p,max_);//判断这朵雪花是不是最大的
                    p++;
                }

            }
        }
    }
    cout<<max_;//输出
}

The end.