codeforces 724c Ray Tracing
好题
原题:
There are k sensors located in the rectangular room of size n × m meters. The i-th sensor is located at point (xi, yi). All sensors are located at distinct points strictly inside the rectangle.
Opposite corners of the room are located at points (0, 0) and (n, m). Walls of the room are parallel to coordinate axes.
At the moment 0, from the point (0, 0) the laser ray is released in the direction of point (1, 1). The ray travels with a speed of
meters per second. Thus, the ray will reach the point (1, 1) in exactly one second after the start.
When the ray meets the wall it's reflected by the rule that the angle of incidence is equal to the angle of reflection. If the ray reaches any of the four corners, it immediately stops.
For each sensor you have to determine the first moment of time when the ray will pass through the point where this sensor is located. If the ray will never pass through this point, print - 1 for such sensors.
2 ≤ n, m ≤ 100 000, 1 ≤ k ≤ 100 000
题意:
在一个m*n的围墙内有一个激光从(0,0)发射,每过1s这个激光的x和y都会+1,如果激光撞到墙上就会反射,方向改变90°,如果撞到墙的四个角就停止,在墙内有k个测试点,现在问激光第一次经过每个测试点的时间是多少
首先易证激光一定会停下来而且每个点只会经过一次
正解是exgcd,思路非常妙
首先如果激光射到墙上,为了简化问题不让这个激光反射而是把这个围墙(连带着里面的探测点)沿着被撞倒的墙对称过去,差不多是酱紫:

然后当这个激光经过所有点的x都等于y,易证lcm(n,m)后激光停下
测试点原坐标为(x,y),随着围墙翻转过去后的坐标是(2*r*n±x,2*q*m±y)
如果翻转偶数次,测试点在围墙内的相对位置没变,坐标=2*r*n+x(这里只拿x举例),如果翻转奇数次,坐标=(2*r-1)*n+n-x=2*r*n-x
酱紫的话就有四种情况,只需要取这四种情况的最小值即可
然后对于每个测试点的每种情况,当两坐标相等的时候这个测试点被激光经过,即2*r*n+x=2*q*m+y(这里拿一种情况举例,其它类似(将x/y变为-x/-y即可))
n,m,x,y都是已知的,边形就可以得到2*n*r+2*m*q=y-x
这个就是exgcd的标准形式(注意只有r和q是未知的)
然后搞exgcd就可以辣
最后判一下无解,进行变化一下就可以得到一种情况的答案,与其它情况比较即可
注意exgcd后得出的x(这里的x不是坐标)需要(x%(b/gcd(a,b))+b/gcd(a,b))%(b/gcd(a,b)),先膜再加是防止负数,再膜一次为了保证取到最小值(如果不膜保证解合法但不一定最小)
代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
#define ll long long
ll read(){ll z=,mark=; char ch=getchar();
while(ch<''||ch>''){if(ch=='-')mark=-; ch=getchar();}
while(ch>=''&&ch<=''){z=(z<<)+(z<<)+ch-''; ch=getchar();}
return z*mark;
}
ll n,m,k,oo;
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
void exgcd(ll a,ll b,ll &x,ll &y){
if(!b){ x=,y=; return ;}
exgcd(b,a%b,x,y);
ll c=x; x=y,y=c-a/b*y;
}
ll q(ll sx,ll sy){
ll a=(n<<),b=-(m<<),c=sy-sx,x,y;
exgcd(a,b,x,y); ll d=gcd(a,b);
if(c%d) return oo;
ll md=abs(b/d);
x*=c/d; x=(x%md+md)%md;//如果不膜解合法但不是最小
ll z=*x*n+sx;
return (z<||z>=oo)?oo:z;
}
ll ans[];
int main(){//freopen("ddd.in","r",stdin);
cin>>n>>m>>k; oo=n*m/gcd(n,m)+;
ll x,y,z;
for(int i=;i<=k;++i){
x=read(),y=read(),z=oo;
z=min(z,q(x,y)),z=min(z,q(-x,-y));
z=min(z,q(-x,y)),z=min(z,q(x,-y));
printf("%I64d\n",(z==oo)?-:z);
}
return ;
}
codeforces 724c Ray Tracing的更多相关文章
- Codeforces 724C Ray Tracing 扩展欧几里得
吐槽:在比赛的时候,压根就没想到这题还可以对称: 题解:http://blog.csdn.net/danliwoo/article/details/52761839 比较详细: #include< ...
- CodeForces 724C Ray Tracing(碰撞类,扩展gcd)
又一次遇到了碰撞类的题目,还是扩展gcd和同余模方程.上次博客的链接在这:http://www.cnblogs.com/zzyDS/p/5874440.html. 现在干脆解同余模直接按照套路来吧,如 ...
- Ray Tracing
Ray Tracing 题目链接:http://codeforces.com/problemset/problem/724/C 拓展欧几里得 //为什么这次C题这么难啊=.= 可以观察到,光线在矩形中 ...
- Intel Code Challenge Final Round (Div. 1 + Div. 2, Combined) C. Ray Tracing 数学
C. Ray Tracing 题目连接: http://codeforces.com/contest/724/problem/C Description oThere are k sensors lo ...
- OpenCascade Ray Tracing Rendering
OpenCascade Ray Tracing Rendering eryar@163.com 摘要Abstract:OpenCascade6.7.0中引入了光线跟踪算法的实现.使用光线跟踪算法可实现 ...
- 开始研究Ray tracing
几个月前面试时Boss问过我一个问题--"除了scanline渲染方法,你还知道什么其他渲染方式?",我没答出来,至今记忆犹新. 前段时间摆弄Intel VTune时看了它的示例代 ...
- 《Ray Tracing in One Weekend》、《Ray Tracing from the Ground Up》读后感以及光线追踪学习推荐
<Ray Tracing in One Weekend> 优点: 相对简单易懂 渲染效果相当好 代码简短,只看书上的代码就可以写出完整的程序,而且Github上的代码是将基类与之类写在一起 ...
- 【Ray Tracing The Next Week 超详解】 光线追踪2-7 任意长方体 && 场景案例
上一篇比较简单,很久才发是因为做了一些好玩的场景,后来发现这一章是专门写场景例子的,所以就安排到了这一篇 Preface 这一篇要介绍的内容有: 1. 自己做的光照例子 2. Cornell box画 ...
- 【RAY TRACING THE REST OF YOUR LIFE 超详解】 光线追踪 3-7 混合概率密度
Preface 注:鉴于很多网站随意爬取数据,可能导致内容残缺以及引用失效等问题,影响阅读,请认准原创网址: https://www.cnblogs.com/lv-anchoret/category ...
随机推荐
- Python 爬虫-股票数据的Scrapy爬虫
2017-08-06 19:52:21 目标:获取上交所和深交所所有股票的名称和交易信息输出:保存到文件中 技术路线:scrapy 获取股票列表:东方财富网:http://quote.eastmone ...
- 很实用且容易忘记的小命令 for Linux(更新中...)
系统相关 # 系统安装日期 sudo tune2fs -l /dev/sda1 |grep create # 查看centos版本命令 rpm -q centos-release #查看centos版 ...
- English trip -- VC(情景课)3 C Do you have a sister?(maple verstion)
xu言: 温故而知新,可以为师矣.不要小瞧重复的东西,不同的老师,不同的角度,不同的方法.你就会掌握不同的知识~ Review what you have learned and get someth ...
- python-day21--os模块
os模块是与操作系统交互的一个接口''' os.getcwd() 获取当前工作目录,即当前python脚本工作的目录路径 os.chdir("dirname") 改变当前脚本工作 ...
- nyoj-1367-河南省第十一届省赛-E物流配送-最小费用流
1367-物流配送 内存限制:128MB 时间限制:8000ms 特判: No通过数:1 提交数:1 难度:4 题目描述: 物流配送是物流活动中一种非单一的业务形式,它与物品流动.资金流动紧密结合.备 ...
- BUCTOJ1073
#include "iostream" #include "algorithm" using namespace std; ; struct Time { in ...
- ORA-14452:试图创建,更改或删除正在使用的临时表中的索引
因为表kol_xx_fin050_temp 为临时表,而且有其他session正在使用. select vs.* from v$session vs , v$lock vl , dba_objects ...
- git commit steps(1)
git commit steps: if you are a new git user , you may need to set # git config --global user.email & ...
- js通过class获取元素
<!doctype html> <html> <head> <meta charset="utf-8"> <meta char ...
- (剑指Offer)面试题59:对称的二叉树
题目: 请实现一个函数,用来判断一颗二叉树是不是对称的. 注意,如果一个二叉树同此二叉树的镜像是同样的,定义其为对称的. 思路: 对于一棵二叉树,从根结点开始遍历, 如果左右子结点有一个为NULL,那 ...