【洛谷】P1789 【Mc生存】插火把 の 题解

这道题貌似一看是个shuiti,但我第一次做 两AC 两WA 一RE

五彩斑斓了属于是

首先请出传送门:P1789 【Mc生存】插火把

我看到好多大佬都用了暴力,为啥就我暴力是错的?!

我重新比对了一下我原来的错代码:

#include<iostream>
using namespace std;
bool p[123][123];
int main()
{
    int n , m , k , x , y , ans = 0;
    cin >> n >> m >> k;
    for(int i = 1;i <= m;i++)
    {
        cin >> x >> y;
        for(int j = x-2;j <= x+2;j++) if(j && j <= n) p[x][j] = p[j][y] = true;
        p[x-1][y-1] = p[x-1][y+1] = p[x+1][y-1] = p[x+1][y+1] = true;
    }
    for(int i = 1;i <= k;i++)
    {
        cin >> x >> y;
        for(int j = x-2;j <= x+2;j++)
            for(int f = x-2;f <= x+2;f++)
                if(j && f && j <= n && f <= n) p[j][f] = true; 
    }
    for(int i = 1;i <= n;i++)
        for(int j = 1;j <= n;j++) if(p[i][j] == false) ans++;
    cout << ans << endl; 
    return 0;
}

如果定睛一看,就很容易发现错误:

首先,我第一个双重循环火把的照亮区域一看就是错的(脑子可能当时抽了)

其次,是最容易错的:

数组越界!!!!!

数组越界!!!!!

数组越界!!!!!

因为如x-2 , y-2 , x+1 , y+1 容易造成数组越界,某些照亮的区域会超出范围,所以需要特别判断(当然我觉得80%的人都不会犯这种错误)

接着,我发现我跟某位大佬不谋而合(!!!)

我们可以把火把照亮的区域分成这样:

0 0 1 0 0

0 1 1 1 0

1 1 2 1 1 // 2表示火把所在位置

0 1 1 1 0

0 0 1 0 0

把中间那个3*3的照亮区域单独拿出来,看作一个矩阵

火把坐标是(x,y)

那么3*3矩阵 左上角的点就是(x-1 , y-1)

右下角的点就是(x+1 , y+1)

然后先把这一部分标记为照亮就行了,当然要注意数组越界的问题!!

接着,还剩下左右上下四行中四个照亮点的位置

如果火把坐标(x,y)

则:

上 (x-2 , y) 下 (x+2 , y)

左 (x , y-2) 右 (x , y+2)

把这四个点也标注出来就OK了,也要注意数组越界的情况

这一部分代码如下:

for(int i = 1;i <= m;i++)
    {
        cin >> x >> y;
        for(int j = x-1;j <= x+1;j++)
            for(int q = y-1;q <= y+1;q++)
                if(j > 0 && q > 0 && j <= n && q <= n) p[j][q] = 1;//p是bool型数组,判断该格是否被照亮
        if(x-2 > 0) p[x-2][y] = 1;
        if(x+2 <= n) p[x+2][y] = 1;
        if(y-2 > 0) p[x][y-2] = 1;
        if(y+2 <= n) p[x][y+2] = 1;
    }

然后萤石的情况就简单啦:

萤石坐标(x,y)

照亮的5*5矩阵中:

左上角(x-2 , y-2)

右下角(x+2 , y+2)

还是要判断数组越界

这一部分的代码是这样的:

for(int i = 1;i <= k;i++)
    {
        cin >> x >> y;
        for(int j = x-2;j <= x+2;j++)
            for(int f = x-2;f <= x+2;f++)
                if(j > 0 && f > 0 && j <= n && f <= n) p[j][f] = true; 
    }

整体的代码就不展示出来了,可以自己动手做做看~

这是本蒟蒻做的第一篇题解,希望大家多多支持!!

  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值