1.P1789 【Mc生存】插火把(来源于:洛谷)
题目描述
话说有一天 linyorson 在“我的世界”开了一个 n×n 的方阵,现在他有 m 个火把和 k 个萤石,分别放在(x1,y1)∼(xm,ym) 和 (o1,p1)∼(ok,pk) 的位置,没有光并且没放东西的地方会生成怪物。请问在这个方阵中有几个点会生成怪物?
P.S. 火把的照亮范围是:
|暗|暗| 光 |暗|暗|
|暗|光| 光 |光|暗|
|光|光|火把|光|光|
|暗|光| 光 |光|暗|
|暗|暗| 光 |暗|暗|
萤石:
|光|光| 光 |光|光|
|光|光| 光 |光|光|
|光|光|萤石|光|光|
|光|光| 光 |光|光|
|光|光| 光 |光|光|
输入格式
输入共m+k+1 行。
第一行为 n,m,k。
第 2 到第 m+1 行分别是火把的位置xi,yi。
第 m+2 到第 m+k+1 行分别是萤石的位置oi,pi。
注:可能没有萤石,但一定有火把。
输出格式
有几个点会生出怪物。
输入输出样例
输入
5 1 0
3 3
输出
12
说明/提示
数据保证,1≤n≤100,1≤m+k≤25,1≤m≤25,0≤k≤5。
题目解析:
我们这里可以利用二维数组,将有东西和有光的地方赋值为1,没光的地方则是怪物生成的地方初始化为0,这样便方便计数
本题要处理两种情况,一个是火把一个是萤石,并且放东西的地方也要赋值为1
【火把】:
我们可以把它处理成这样:
0 0 1 0 0
0 0 0 0 0
1 0 0 0 1
0 0 0 0 0
0 0 1 0 0
这里特殊的四个位置直接赋值就好啦
加上:
0 0 0 0 0
0 1 1 1 0
0 1 1 1 0
0 1 1 1 0
0 0 0 0 0
这里我们可以直接用一个双重For循环就能处理完
【萤石】:
直接用双重For循环进行遍历就好啦
注意:
这里要处理x-2和y-2的时候要注意处理数组越界问题,要是不处理样例过不了直接RE
所以我们将数组整体位置往前移2格,这样就不会存在数组越界问题啦!!!(跟大佬学的)
代码参考:
#include<bits/stdc++.h>
using namespace std;
const int N=105;
int q[N][N];
int main(){
int n,m,k;
cin>>n>>m>>k;
while(m--){ //处理火把
int x1,y1;
cin>>x1>>y1;
//处理数组越界问题
x1+=2;
y1+=2;
//处理四个特殊位置
q[x1][y1-2]=1;
q[x1][y1+2]=1;
q[x1+2][y1]=1;
q[x1-2][y1]=1;
//处理小正方形的位置
for(int i=x1-1;i<=x1+1;i++){
for(int j=y1-1;j<=y1+1;j++){
q[i][j]=1;
}
}
}
while(k--){//萤石
int x2,y2;
cin>>x2>>y2;
x2+=2;
y2+=2;
for(int i=x2-2;i<=x2+2;i++){
for(int j=y2-2;j<=y2+2;j++){
q[i][j]=1;
}
}
}
int res=0;
for(int i=1+2;i<=n+2;i++){ //数组初始位置向后移2个
for(int j=1+2;j<=n+2;j++){
if(q[i][j]==0) res++; //当数字为零则表示有怪物,累加
}
}
cout<<res<<endl;
return 0;
}