啊丢的刷题记录(洛谷题单数组篇)

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;
} 

  • 10
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值