题解 P1789 【【Mc生存】插火把】

· · 题解

思路很简单,代码长一点但是还好理解吧(个人这么认为),of course,我的思路都写在代码里了(防抄袭党),寄己看代码去吧。

#include <bits/stdc++.h>
#define rg register int //为了减少循环变量的内存 
using namespace std;
bool cheap[10000][10000]={0};//画一个地图,bool的内存占用量小 
int n,m,k;//数量 
int li,yi;//坐标 
void ys(int x,int y){//萤石的范围 
    for(rg i=x-2;i<=x+2;i++)//上下各五层 
       for(rg j=y-2;j<=y+2;j++)
       if(i>n||i<1||j>n||j<1) continue;//如果大于总数或者非正数就跳过 
       else   cheap[i][j]=1;//否则标记 
    return ; //返回上一步 
}
void hb(int x,int y){//火把要麻烦一点 
    for(rg i=y-2;i<=y+2;i++)//首先是火把所在的那一层 
    if(i>n||i<1) continue;//如果超出范围就跳过 
    else cheap[x][i]=1;//标记 
    for(rg i=x-1;i<=x+1;i++)//再是火把上面和下面 
           for(rg j=y-1;j<=y+1;j++)//上面和下面各3个位置 
           if(i>n||i<1||j>n||j<1) continue;//超出范围就跳过 
           else cheap[i][j]=1;//标记 
    if(x+2<=n)//火把可以照亮的最上面,未超范围 
    cheap[x+2][y]=1;//标记 
    if(x-2>0)//火把可以照亮的最下面,未超范围 
    cheap[x-2][y]=1;//标记
    return ;//返回上一步 
}
int find(){//找总共还有几个点没有标记 
    int val=0;
    for(rg i=1;i<=n;i++)
           for(rg j=1;j<=n;j++)
           if(cheap[i][j]==0)
           val++;
    return val;
}
int main(){
    cin>>n>>m>>k;
    for(rg i=1;i<=m;i++)
           cin>>li>>yi,hb(li,yi);//边读边处理 
    for(rg i=1;i<=k;i++)
           cin>>li>>yi,ys(li,yi);
    cout<<find();//输出找到的 
}