AT_abc182_e [ABC182E] Akari题解

发布时间 2023-08-17 22:54:16作者: Code_Fish_Hp

题目链接

思路

说实话,这道题其实算模拟,还是挺简单的那种。我们可以定一个 int 类型的二维数组,表示网格。通过不同的数字来表示该方格内不同的类型。然后,使用枚举法模拟网格内灯泡从上、下、左、右四个方向模拟光线的运动过程,在过程中增加可被照射到的格子数量,最后输出即可。


坑点:

  • 灯泡所在的方格也会有光照。
  • 被光照照到且没有障碍物的方格有多少。

参考代码(请勿抄袭):

#include<bits/stdc++.h>
using namespace std;
int cv[1510][1510],h,w,n,m; //对于cv数组内的每一个数,如果值为0,则代表当前是没有照的空地,如果是1,代表是被照的空地,如果是2,代表灯泡,如果是3,代表是障碍物。
bool flag=false;
long long outp=0;

int main(){
	memset(cv,0,sizeof(cv));//假设全是空地
	scanf("%d%d%d%d",&h,&w,&n,&m);//输入
	outp+=n;//灯泡也算 
	for(int i=1;i<=n;i++){//灯泡 
		int xi,yi;
		scanf("%d%d",&xi,&yi);
		cv[xi][yi]=2;
	}
	for(int i=1;i<=m;i++){//障碍 
		int xi,yi;
		scanf("%d%d",&xi,&yi);
		cv[xi][yi]=3;
	}
	for(int i=1;i<=h;i++){//往右走 
		flag=false;//初始化·不能继续
		for(int j=1;j<=w;j++){
			if(cv[i][j]==2) flag=true;//可以继续(有灯泡)	
			else if(cv[i][j]==3) flag=false;//不可以继续(遇到障碍物)
			if(flag==true&&cv[i][j]==0){//可以照并且未被照 
				cv[i][j]=1;
				outp++;
			}
		} 
	}
	for(int i=1;i<=h;i++){//往左走 
		flag=false;//初始化·不能继续
		for(int j=w;j>=1;j--){
			if(cv[i][j]==2) flag=true;//可以继续(有灯泡)	
			else if(cv[i][j]==3) flag=false;//不可以继续(遇到障碍物)
			if(flag==true&&cv[i][j]==0){//可以照并且未被照 
				cv[i][j]=1;
				outp++;
			}
		} 
	}
	for(int j=w;j>=1;j--){//往上走 
		flag=false;//初始化·不能继续
		for(int i=h;i>=1;i--){
			if(cv[i][j]==2) flag=true;//可以继续(有灯泡)	
			else if(cv[i][j]==3) flag=false;//不可以继续(遇到障碍物)
			if(flag==true&&cv[i][j]==0){//可以照并且未被照 
				cv[i][j]=1;
				outp++;
			}
		} 
	}
	for(int i=w;i>=1;i--){//往下走 
		flag=false;//初始化·不能继续
		for(int j=1;j<=h;j++){
			if(cv[j][i]==2) flag=true;//可以继续(有灯泡)	
			else if(cv[j][i]==3) flag=false;//不可以继续(遇到障碍物)
			if(flag==true&&cv[j][i]==0){//可以照并且未被照 
				cv[j][i]=1;
				outp++;
			}
		} 
	}
	printf("%d",outp);//输出结果
	return 0;
}