传送门

题意:

n×m的网格上,有k个镜子,光线反射规则如下:

现在给出初始光线的位置以及光线的射出方向,求光线能经过多少个格子的中心

光线走到边缘也会被反射

n,m,k<=1e5

Solution:

暴力模拟即可,但是大家可能会想到一点:光线可能会经过重复的砖块的中心,但是仔细思考一下就会发现这种情况是不可能发生的,因为每次如果不是原路返回的反射的话光线的坐标x+y的奇偶性就会改变

这样一来就简单了,我们开n+m-1个vector记录每一条主对角线和副对角线上的镜子的位置,然后每次射出光线时在对应的对角线上二分查找即可

注意如果出现原路返回的反射的话需要从原位置反方向再搞一遍

写的时候还发现如果初始位置处于一条光路的中间位置的话统计答案会很难办,所以我们可以先让光线射一次,然后再执行我们的算法

细节比较多的一道题,可以用来练习代码能力

代码(可能写的比较丑QWQ):

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<map>
#include<vector>
#define mp(a,b) make_pair(a,b)
using namespace std;
const int N=100010;
int n,m,k,x,y;
char s[5];
struct mirror{int x,y;
}q[N];
vector<int>zhu[2*N],fu[2*N];
map<pair<int,int>,bool>vis;
map<pair<int,int>,bool>p;
int id;
int dx,dy;
long long ans,tot;
int find(bool x,int i,int l,int r,int pos)
{int as=-1;if (x==1){while (l<=r){int mid=l+r>>1;if (zhu[i][mid]<pos) as=zhu[i][mid],l=mid+1;//SWelse r=mid-1;}return as;}else{while (l<=r){int mid=l+r>>1;if (fu[i][mid]<pos) as=fu[i][mid],l=mid+1;//NWelse r=mid-1;}return as;}
}
int findbig(bool x,int i,int l,int r,int pos)
{int as=-1;if (x==1){while (l<=r){int mid=l+r>>1;if (zhu[i][mid]>pos) as=zhu[i][mid],r=mid-1;//SWelse l=mid+1;}return as;}else{while (l<=r){int mid=l+r>>1;if (fu[i][mid]>pos) as=fu[i][mid],r=mid-1;//NWelse l=mid+1;}return as;}
}
bool run(int dx,int dy,int x,int y)
{tot=0;while (!p[mp(x,y)]){p[mp(x,y)]=1;if (dx+dy==0){if (dx==1)//SW{int pos=find(1,x+y-1,0,zhu[x+y-1].size()-1,y);//zhutot+=y-pos;x=x+y-1-pos;y=pos+1;if (vis[mp(x+1,y)]&&vis[mp(x,y-1)]) return 0;else if (vis[mp(x+1,y)]) dx=-dx,y--;else if (vis[mp(x,y-1)]) dy=-dy,x++;else return 0;}else//NE{int pos=findbig(1,x+y-1,0,zhu[x+y-1].size()-1,y);//zhutot+=pos-y;x=x+y-1-pos+2;y=pos-1;if (vis[mp(x-1,y)]&&vis[mp(x,y+1)]) return 0;else if (vis[mp(x-1,y)]) dx=-dx,y++;else if (vis[mp(x,y+1)]) dy=-dy,x--;else return 0;}}else{if (dx==-1)///NW{int pos=find(0,m-y+x,0,fu[x+m-y].size()-1,y);tot+=y-pos;x=x-y+pos+1;y=pos+1;if (vis[mp(x-1,y)]&&vis[mp(x,y-1)]) return 0;else if (vis[mp(x-1,y)]) dx=-dx,y--;else if (vis[mp(x,y-1)]) dy=-dy,x--;else return 0;}else//SE{int pos=findbig(0,m-y+x,0,fu[x+m-y].size()-1,y);//zhutot+=pos-y;x=x-y+pos-1;y=pos-1;if (vis[mp(x+1,y)]&&vis[mp(x,y+1)]) return 0;else if (vis[mp(x+1,y)]) dx=-dx,y++;else if (vis[mp(x,y+1)]) dy=-dy,x++;else return 0;}}}return 1;
}
int main()
{scanf("%d%d%d",&n,&m,&k);for (int i=1;i<=k;i++){scanf("%d%d",&q[i].x,&q[i].y);vis[mp(q[i].x,q[i].y)]=1;zhu[q[i].x+q[i].y-1].push_back(q[i].y);fu[m-q[i].y+q[i].x].push_back(q[i].y);}for (int i=0;i<=n;i++){vis[mp(i,0)]=1;zhu[i+0-1].push_back(0);fu[m-0+i].push_back(0);}for (int i=n+1;i>0;i--){vis[mp(i,m+1)]=1;zhu[i+m+1-1].push_back(m+1);fu[m-(m+1)+i].push_back(m+1);}for (int i=0;i<=m;i++){vis[mp(n+1,i)]=1;zhu[n+1+i-1].push_back(i);fu[m-i+n+1].push_back(i);}for (int i=m+1;i>0;i--){vis[mp(0,i)]=1;zhu[0+i-1].push_back(i);fu[m-i+0].push_back(i);}for (int i=1;i<=n+m-1;i++) sort(zhu[i].begin(),zhu[i].end()),sort(fu[i].begin(),fu[i].end()); scanf("%d%d%s",&x,&y,s);if (s[0]=='N'&&s[1]=='E') dx=-1,dy=1;else if (s[0]=='N'&&s[1]=='W') dx=-1,dy=-1;else if (s[0]=='S'&&s[1]=='W') dx=1,dy=-1;else if (s[0]=='S'&&s[1]=='E') dx=1,dy=1;if (dx+dy==0){if (dx==1)//SW{int pos=find(1,x+y-1,0,zhu[x+y-1].size()-1,y);//zhux=x+y-1-pos;y=pos+1;if (vis[mp(x+1,y)]&&vis[mp(x,y-1)]) dx=-dx,dy=-dy;else if (vis[mp(x+1,y)]) dx=-dx,y--;else if (vis[mp(x,y-1)]) dy=-dy,x++;else dx=-dx,dy=-dy;}else//NE{int pos=findbig(1,x+y-1,0,zhu[x+y-1].size()-1,y);//zhux=x+y-1-pos+2;y=pos-1;if (vis[mp(x-1,y)]&&vis[mp(x,y+1)]) dx=-dx,dy=-dy;else if (vis[mp(x-1,y)]) dx=-dx,y++;else if (vis[mp(x,y+1)]) dy=-dy,x--;else dx=-dx,dy=-dy;}}else{if (dx==-1)///NW{int pos=find(0,m-y+x,0,fu[x+m-y].size()-1,y);x=x-y+pos+1;y=pos+1;if (vis[mp(x-1,y)]&&vis[mp(x,y-1)]) dx=-dx,dy=-dy;else if (vis[mp(x-1,y)]) dx=-dx,y--;else if (vis[mp(x,y-1)]) dy=-dy,x--;else dx=-dx,dy=-dy;}else//SE{int pos=findbig(0,m-y+x,0,fu[x+m-y].size()-1,y);//zhux=x-y+pos-1;y=pos-1;if (vis[mp(x+1,y)]&&vis[mp(x,y+1)]) dx=-dx,dy=-dy;else if (vis[mp(x+1,y)]) dx=-dx,y++;else if (vis[mp(x,y+1)]) dy=-dy,x++;else dx=-dx,dy=-dy;}}if (run(dx,dy,x,y)) printf("%lld",tot);else{ans=tot-1;p[mp(x,y)]=0;dx=-dx,dy=-dy;run(dx,dy,x,y);ans+=tot;printf("%lld",ans);}
}

Codeforces 274E. Mirror Room-模拟+STL相关推荐

  1. 模拟STL链表类的实现

    模拟STL链表类的实现 STL内部定义了多种容器和迭代器,方便了数据结构类的使用,且不需关注内部源码.为了方便个人使用习惯,我又重写了一个链表类,作为学C++后的第一个项目作业.我将其命名为clist ...

  2. PAT (Basic Level) 1091 N-自守数(模拟+stl)

    题目链接:点击查看 题目大意:给定一个数K,规定N-自守数的定义为K*K*N的末尾几位数等于K,则称K为N-自守数,比如3*92*92=25392,所以92是一个3-自守数,现在给出一些数,判断其是不 ...

  3. PAT (Basic Level) 1080 MOOC期终成绩(模拟+stl)

    题目链接:点击查看 题目大意:分别给出a个学生的编程分数,b个学生的期中考试成绩,c个学生的期末考试成绩,有几个规则: 总评为: 若期中考试成绩大于期末考试成绩: 否则: 合格的定义是编程分数大于等于 ...

  4. HDU4841 圆桌问题【约瑟夫环+模拟+STL】

    圆桌问题 Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others) Total Submissi ...

  5. CodeForces - 1526D Kill Anton(模拟)

    题目链接:https://vjudge.net/problem/CodeForces-1526D 题目大意:给出一个只有四种字母组成的字符串 AAA,要求将其重排列 BBB,使得贡献最大.贡献指的是, ...

  6. PAT (Basic Level) 1095 解码PAT准考证(模拟+stl,好题)

    题目链接:点击查看 题目大意:给出n个学生的准考证号以及成绩,再给出m个查询,要求按照规则输出每一个查询 首先,准考证的构成也是有讲究的,每个准考证号由四部分组成: 第一位是级别,A代表甲级,B代表乙 ...

  7. Codeforces Gym 100286I iSharp 模拟

    原题地址:http://codeforces.com/gym/100286/attachments/download/2013/20082009-acmicpc-northeastern-europe ...

  8. Pyramid of Glasses CodeForces - 676B (dp,模拟)

    题目:新冠病毒肆虐了好几个月,彻底打乱了大家的学习和生活,终于在阳光明媚的某月,全球迎来了新冠抗战的顺利.为了庆祝全球协力共同抗疫的顺利,同学们准备了一场庆祝晚会,一起幻想以后美好的生活,他们用香槟酒 ...

  9. Codeforces 770D Draw Brackets! 模拟+中缀表达式

    http://codeforces.com/problemset/problem/770/D 我先找出每个括号'+'的位置和每个s[i]的高度 括号一定会出现[],就是s[i]='[' s[i+1]= ...

  10. CodeForces - 1141ESuperhero Battle简单模拟

    Superhero Battle 这道题卡了我一个多小时,最后也没有做出来,成功称为吊车尾... 思路什么的都没有问题,主要是,爆long long了,这个太可怕了,就因为一个中间变量忘记开longl ...

最新文章

  1. (纪录片)统计的乐趣 The Joy of Stats (2010)
  2. Linux kernel 编译问题记录【转】
  3. 2012年上海市高等学校计算机等级考试试卷,2012年上海市高等学校计算机等级考试A试卷...
  4. 获取当前图层所处的坐标系统(C++)(ArcObject开发)
  5. matlab sunlink工具箱,FreeBSD handbook Unix Basics
  6. Project Euler 97 :Large non-Mersenne prime 非梅森大素数
  7. 【分享】U盘大小的随身电脑 – Cotton Candy
  8. ​rsync守护进程模式实践排错08
  9. 判断字符串是只是数字
  10. html登陆滑动验证,js实现滑动滑块验证登录的方法
  11. iwconfig 安装_嵌入式wifi iwconfig编译
  12. [科普文] 搞 Web3 要学习哪些基础知识?
  13. linux用户态和内核态堆栈,Linux内核态、用户态简介与IntelCPU特权级别--Ring0-3
  14. 人活着的三种境界[转帖]
  15. 端口号,UDP,TCP
  16. 求阶乘的和(C++)
  17. MacPro下VirtualBox安装Windows7虚拟机太卡的解决方法
  18. Web前端工程师必备的PS技能之切图
  19. 宏碁华硕平板先过山寨iPad这道坎
  20. 大学英语b级和计算机b,网络统考丨大学英语B级,6大题型及答题技巧!【零基础学员必看】...

热门文章

  1. [玩法/技巧] Transmission 3.0 降级到 2.94 恢复数据的方法
  2. 【项目管理】测量绩效域管理
  3. rtl8201以太网卡调试
  4. 插座断电提醒(测试阶段)
  5. Maya无法创建新模型解决方案1
  6. 360校招 求立方体表面积
  7. ecshop模板支持php,解决ecshop模板不支持php代码,修改ecshop过滤模板php代码!
  8. mas6a801 sw tree disp
  9. 西门子plc200 c语言转换,西门子S7-200 系列PLC量程转换及编程方法
  10. HTML无法显示下一页,为何我的浏览器不能直接打开下一页