首页 > 其他分享 >2024牛客多校第一场 - Mirror Maze

2024牛客多校第一场 - Mirror Maze

时间:2024-10-05 16:45:25浏览次数:1  
标签:return int light rev 多校 2024 牛客 include dir

题目大意:一个由四种镜面(| - / \)组成的矩阵,根据镜面的方向反射光线。问坐标 \((x,y)\) 处向某方向射入一束光线后(此光线会直接穿过此位置 \((x,y)\) 的镜面),一共会反射(直接穿过的不算)到多少个不同(一个坐标算一个镜面)的镜面。

总体思路为预处理出每一个坐标向每一个位置发射光线的答案。

处理“不同”的镜面可以直接用 set 记录坐标并去重,最后求 size

由于光路可逆,所以光路没有分叉或汇合的情况,故所有的路径一定是环或链

先考虑链的情况:因为链的尽头一定是边界,所以从四个边界向内发射光线。通过光路可逆将“抵达该坐标时朝向某方向”转化为“离开某坐标时朝向它的反方向”,这样就可以避免递归(会爆栈)或手动堆栈(懒得写)。即在遍历一条光路的时候记录的时它的反向光路的答案。

再考虑环的情况。去除所有的链以后,剩下的还未被访问到的点及方向(注意是某个点的某个方向,不单指这个点)就都在环内。在这些地方和方向再分别发射一条光线进行遍历。当走到已访问过的点时说明走完了一个完整的环。途中记录的环大小(即 set 的大小)就是中途每一个点及方向的答案。

注意记录访问需要单独一个 vst 数组,因为查链的时候可能出现在一条链内但答案是 \(0\) 的情况。

代码如下:

#include<set>
#include<map>
#include<cstdio>
#include<string>
#include<vector>
#include<cstring>
#include<iostream>
#include<unordered_map>
using namespace std;

const int N=1005;
int n,m,q;
char str[N][N];
int maze[N][N];

const int rotation[10][10]={
	{0,0,0,0,0},
	{0,1,2,4,3}, // '|'
	{0,2,1,3,4}, // '-'
	{0,4,3,2,1}, // '/'
	{0,3,4,1,2}  // '\'
};
const int trans_x[10]={0,-1,1,0,0};
const int trans_y[10]={0,0,0,-1,1};
const int rev_direction[10]={0,2,1,4,3};
map<string,int> DIR={{"above",1},{"below",2},{"left",3},{"right",4}};
map<char,int> MIR={{'|',1},{'-',2},{'/',3},{'\\',4}};

struct Rain{
	int x,y;
	int dir; // 1↑ 2↓ 3← 4→ | 进入方向 
	void step() //先转再走 
	{
		dir=rotation[maze[x][y]][dir];
		x+=trans_x[dir],y+=trans_y[dir];
		return;
	}
	bool chg_dir(){return dir!=rotation[maze[x][y]][dir];} //是否改变方向
	bool check(){return x>=1&&x<=n && y>=1&&y<=m;}
};
int rev_dir(int dir){return rev_direction[dir];}

int ans[N][N][6];
bool vst[N][N][6];

void Biu(Rain light)
{
	set<pair<int,int>> reflect;
	while(light.check())
	{
		ans[light.x][light.y][rev_dir(light.dir)]=reflect.size();
		vst[light.x][light.y][rev_dir(light.dir)]=true;
		if(light.chg_dir()) reflect.insert({light.x,light.y});
		light.step();
	}
	return;
}
void Prework_chain()
{
	for(int i=1;i<=n;i++)
	{
		Biu({i,1,4});
		Biu({i,m,3});
	}
	for(int i=1;i<=m;i++)
	{
		Biu({1,i,2});
		Biu({n,i,1});
	}
	return;
}

void Pu(Rain light)
{
	set<pair<int,int>> reflect;
	vector<Rain> path;
	while(!vst[light.x][light.y][rev_dir(light.dir)])
	{
		vst[light.x][light.y][rev_dir(light.dir)]=true;
		if(light.chg_dir()) reflect.insert({light.x,light.y});
		path.push_back(light);
		light.step();
		if(!light.check()) return;
	}
	for(Rain x:path)
		ans[x.x][x.y][rev_dir(x.dir)]=reflect.size();
	return;
}
void Prework_cycle()
{
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
			for(int k=1;k<=4;k++)
				if(!vst[i][j][k]) Pu({i,j,rev_dir(k)});
	return;
}

int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
	{
		scanf("%s",str[i]+1);
		for(int j=1;j<=m;j++)
			maze[i][j]=MIR[str[i][j]];
	}
	Prework_chain();
	Prework_cycle();
	scanf("%d",&q);
	for(int i=1;i<=q;i++)
	{
		int x,y; scanf("%d%d",&x,&y);
		string dir; cin>>dir;
		printf("%d\n",ans[x][y][DIR[dir]]);
	}
	return 0;
}

标签:return,int,light,rev,多校,2024,牛客,include,dir
From: https://www.cnblogs.com/jerrycyx/p/18447987

相关文章

  • 2024.10.5 LGJ Round
    A给定\(n\)个区间,你要选出最多区间对数,使得每一对的区间都不交。\(n\le4e5\)。反悔贪心,我们将所有区间按\(l_i\)从小到大排序,一个一个加入,加入的时候有两种情况。1.之前的区间中存在未匹配的区间,且可以跟当前区间匹配。我们随便选择一个区间跟当前区间匹配即可。2.找不到......
  • 2024-2025 20242307
    我的作业1,以上内容没有掌握没有我掌握的......
  • 2024年——博士延期第8年有感
    刚和期刊编辑社沟通邮件,被告知已接收录用的期刊排期为明年(2025年)5月份出版发表,然后我接到邮件后马上去翻找大连理工大学的博士毕业的要求,然后又赶紧去查了一下这个期刊的中科院SCI分区排名,最后得出一个结论,那就是学校要求论文得分6分才允许答辩,但是必须有一篇论文是已发表,而我现在......
  • [DMY]2024 CSP-S 模拟赛 Day 10
    赛时对于T1,看懂题面以后感觉很可做。首先明确正解复杂度应该是基于\(N\)额度线性做法。把输入按照开始时间排序,然后依次处理。赛时考虑到一个元素在覆盖过程中遇到其他元素时无法确定时间先后,确定后想要找到该元素的当前位置和重新覆盖有些困难,写了1h以后先放弃了。舍远......
  • 蓝桥杯2024年第十五届省赛A组-有奖问答
    题目描述小蓝正在参与一个现场问答的节目。活动中一共有30道题目,每题只有答对和答错两种情况,每答对一题得10分,答错一题分数归零。小蓝可以在任意时刻结束答题并获得目前分数对应的奖项,之后不能再答任何题目。最高奖项需要100分,所以到达100分时小蓝会直接停止答题。......
  • R3CTF2024 WP
    一、PWN1.Nullullullllu在直接给libc_base的情况下,一次任意地址写\x00。直接修改 IO_2_1_stdin 的_IO_buf_base末尾为\x00,那么_IO_buf_base就会指向 IO_2_1_stdin 的_IO_write_base,接下来就是利用getchar函数触发写操作修改 IO_buf_base 为 IO_2_1_stdout ,再......
  • [赛记] 多校A层冲刺NOIP2024模拟赛01【衡中】
    构造字符串50pts错解50pts;考虑正解,对于题目中的要求,我们可以转换成若干个相等与不等的操作,若相等则用并查集合并一下,不等则连边,若同块连边则无解,否则从前往后遍历赋值,每次找所连边其它块值的$\operatorname{mex}$即可;时间复杂度:$\Theta(nm\alpha(n))$;点击查看代码#i......
  • WMCTF 2024 wp
    WEBPasswdStealer前言本来题目叫PasswdStealer的:)考点就是CVE-2024-21733在SpringBoot场景下的利用。漏洞基本原理参考 https://mp.weixin.qq.com/s?__biz=Mzg2MDY2ODc5MA==&mid=2247484002&idx=1&sn=7936818b93f2d9a656d8ed48843272c0不再赘述。SpringBoot场景下的利用前文的分析......
  • 2024.10.4(周五)
    <%@pagelanguage="java"contentType="text/html;charset=UTF-8"pageEncoding="UTF-8"%><!DOCTYPEhtml><html><head><title>工资核算信息</title><style>/*整体页面布局和样式*/......
  • 2024.10.7(周一)
    <%@pagelanguage="java"contentType="text/html;charset=UTF-8"pageEncoding="UTF-8"%><!DOCTYPEhtml><html><head><title>车间班组</title><style>/*整体页面布局和样式*/......