题解 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();//输出找到的
}