1 条题解

  • 0
    @ 2025-8-24 22:52:56

    自动搬运

    查看原文

    来自洛谷,原作者为

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

    搬运于2025-08-24 22:52:56,当前版本为作者最后更新于2023-12-16 11:00:23,作者可能在搬运后再次修改,您可在原文处查看最新版

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

    以下是正文


    P9908 [COCI 2023/2024 #2] Pahuljice

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

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

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

    审题又分为 33 步走

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

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

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

    • 雪花的中间是一个 +
    • 在'+'的上方和下方各有 xx|
    • 在'+'的左方和右方各有 xx-
    • 在'+'的左上方和右下方各有 xx/
    • 在'+'的左下方和右上方各有 xx\
    //雪花大小为2:
    /*
    \.|./
    .\|/.
    --+--
    ./|\.
    /.|.\
    */
    

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

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

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

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

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

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

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

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

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

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

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

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

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

    我们先在“图”中寻找 +,如果找到了就立即开始计算其大小。怎么算呢?先前不是提到了吗?找一个 pp 来帮忙,来帮助我们确定 nn 的值也就是大小了。pp 作为偏移量一开始为 11 随后慢慢加大直到判断为这不再是一朵雪花为止,而此时雪花的大小也就确定了,也就是 p1p-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.

    • 1

    信息

    ID
    9505
    时间
    1000ms
    内存
    512MiB
    难度
    2
    标签
    递交数
    0
    已通过
    0
    上传者