原文链接http://www.cnblogs.com/zhouzhendong/p/9055728.html

题目传送门 - Codeforces 928E

题意

  一束与坐标轴平行或者成$45^\circ$角的光线在一个矩形区域内反射。

  如图:

  

  给定矩形的长宽,以及光源位置、光线初始方向,问它最先到达四个角落中的哪一个角落。如果永远不能到达,输出$-1$。

题解

  本来不想写的。本次CF又打烂了。

  D题一个傻逼错误调了40多分钟。

  E题貌似挺可做的。可是来不及啊。(再加上深更半夜神志不清)

  

  我们来回顾一下初中数学套路。

  考虑将每次反射做一个对称。

  我来画一下一组数据:

  5 3 4 0 1 1

  

  通过对称,我们把它画成这样(经典初中数学套路):

  

  然后问题就大致变成了求直线到达的第一个满足$n|T_x,m|T_y$的点$(T_x,T_y)$。

  为了方便,我们再把原图画成这样:

  

  问题进一步简化,变成从$s'$出发的问题了。

  设$S=(x,y)$,则$S'=(0,y-x)$,

  不难列出方程:

  $an+(y-x)=bm \Longrightarrow an+bm=(x-y)$

  然后我们用exgcd来解一下这个方程,首先判掉无解的情况,输出$-1$。

  然后注意一下我们要求的是第一个碰到的这样的点,所以在特殊情况的时候要小心。

  要取$a$的尽量小的正整数值。我一开始写错了,对$m$取模,然后突然发现应该对$m/gcd(n,m)$取模……

  然后根据算出来的$a$以及$b$的奇偶性来确定到达的位置。

  至于一开始输入的:

    如果是平行坐标轴的,那么直接判掉。

    如果是$45^\circ$的,那么我们可以通过在原矩形中取对称来使其变成我们需要的那样。

  题外话:

  又错失一次上黄的机会QAQ。

  话说我的代码跑的挺快的。

  话说为什么目前我$friends$里面的三位大佬(xza,bestfy,emoairx)的代码怎么都要跑几百$MS$……后来才发现他们的那个循环好像不是$O(1)$的……

  QAQ大佬都会写循环……只有我这种菜鸡才去写公式。关键是还写挂了调了有一会儿……(就是之前提到过的那个问题)

代码

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
int n,m,x,y,vx,vy;
int refx,refy;
LL exgcd(LL a,LL b,LL &x,LL &y){
if (!b){
x=1,y=0;
return a;
}
LL res=exgcd(b,a%b,y,x);
y-=(a/b)*x;
return res;
}
int main(){
scanf("%d%d%d%d%d%d",&n,&m,&x,&y,&vx,&vy);
if (vx==0){
if (x==0||x==n){
if (vy==1)
printf("%d %d\n",x,m);
else
printf("%d %d\n",x,0);
}
else
puts("-1");
return 0;
}
if (vy==0){
if (y==0||y==m){
if (vx==1)
printf("%d %d\n",n,y);
else
printf("%d %d\n",0,y);
}
else
puts("-1");
return 0;
}
if (vx==-1)
refx=1,x=n-x;
if (vy==-1)
refy=1,y=m-y;
//s'=(0,y-x)
//an+(y-x)=bm => an+bm=(x-y)
LL a,b,g;
g=exgcd(n,m,a,b);
if ((x-y)%g!=0){
puts("-1");
return 0;
}
LL t=(x-y)/g;
a*=t,b*=t;
int _m=m/g,_n=n/g;
LL _a=(a%_m+_m+_m-1)%_m+1,_b=-((x-y)-_a*n)/m;
LL ansx=n,ansy=m;
if (_a%2==0)
ansx=n-ansx;
if (_b%2==0)
ansy=m-ansy;
if (refx)
ansx=n-ansx;
if (refy)
ansy=m-ansy;
printf("%I64d %I64d",ansx,ansy);
return 0;
}

  

Codeforces 982E Billiard 扩展欧几里德的更多相关文章

  1. Codeforces 982E Billiard exgcd

    Billiard 枚举终点, 对于每一个终点一共有四种周期的相遇方式, 枚举一下取最小的时间. #include<bits/stdc++.h> #define LL long long # ...

  2. 欧几里德和扩展欧几里德详解 以及例题CodeForces 7C

    欧几里德定理: 对于整数a,b来说,gcd(a, b)==gcd(b, a%b)==d(a与b的最大公约数),又称为辗转相除法 证明: 因为a是d的倍数,b是d的倍数:所以a%d==0:b%d==0: ...

  3. CodeForces 146E - Lucky Subsequence DP+扩展欧几里德求逆元

    题意: 一个数只含有4,7就是lucky数...现在有一串长度为n的数...问这列数有多少个长度为k子串..这些子串不含两个相同的lucky数... 子串的定义..是从这列数中选出的数..只要序号不同 ...

  4. (扩展欧几里德算法)zzuoj 10402: C.机器人

    10402: C.机器人 Description Dr. Kong 设计的机器人卡尔非常活泼,既能原地蹦,又能跳远.由于受软硬件设计所限,机器人卡尔只能定点跳远.若机器人站在(X,Y)位置,它可以原地 ...

  5. [BZOJ1407][NOI2002]Savage(扩展欧几里德)

    题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1407 分析: m,n范围都不大,所以可以考虑枚举 先枚举m,然后判定某个m行不行 某个 ...

  6. 欧几里德与扩展欧几里德算法 Extended Euclidean algorithm

    欧几里德算法 欧几里德算法又称辗转相除法,用于计算两个整数a,b的最大公约数. 基本算法:设a=qb+r,其中a,b,q,r都是整数,则gcd(a,b)=gcd(b,r),即gcd(a,b)=gcd( ...

  7. 51nod 1352 扩展欧几里德

    给出N个固定集合{1,N},{2,N-1},{3,N-2},...,{N-1,2},{N,1}.求出有多少个集合满足:第一个元素是A的倍数且第二个元素是B的倍数. 提示: 对于第二组测试数据,集合分别 ...

  8. CF 7C. Line(扩展欧几里德)

    题目链接 AC了.经典问题,a*x+b*y+c = 0整数点,有些忘记了扩展欧几里德,复习一下. #include <cstdio> #include <iostream> # ...

  9. poj2142-The Balance(扩展欧几里德算法)

    一,题意: 有两个类型的砝码,质量分别为a,b;现在要求称出质量为d的物品, 要用多少a砝码(x)和多少b砝码(y),使得(x+y)最小.(注意:砝码位置有左右之分). 二,思路: 1,砝码有左右位置 ...

随机推荐

  1. jetty去掉项目名称访问

    对于web项目,访问路径是否包含项目名称等修改访问路径的配置方式: 我所使用的是maven进行管理,只需要在pom.xml中进行如下配置 <!-- jetty插件 jetty:run--> ...

  2. MySQL建库建表

    一直使用SQL SERVER 数据库:最近项目使用MY SQL感觉还是有一点不适应.不过熟悉之后就会好很多. MY SQL 安装之后会有一个管理工具MySQL Workbench 感觉不太好用,数据库 ...

  3. Goland could not launch process: decoding dwarf section info at offset 0x0: too short 解决方案

    1 前言 Goland版本:2018.1.5 Go:1.11.2 此版本调试不了bug,而且有时会显示could not launch process: decoding dwarf section ...

  4. 并发性能的隐形杀手之伪共享(false sharing)

    在并发编程过程中,我们大部分的焦点都放在如何控制共享变量的访问控制上(代码层面),但是很少人会关注系统硬件及 JVM 底层相关的影响因素.前段时间学习了一个牛X的高性能异步处理框架 Disruptor ...

  5. Codeforces 1045G AI robots [CDQ分治]

    洛谷 Codeforces 简单的CDQ分治题. 由于对话要求互相看见,无法简单地用树套树切掉,考虑CDQ分治. 按视野从大到小排序,这样只要右边能看见左边就可以保证互相看见. 发现\(K\)固定,那 ...

  6. Confluence 6 用户宏示例 - Hello World

    下面示例显示了如何创建一个用户宏,在这个用户宏中显示文本 'Hello World!' 和任何用户在宏内容中输入的内容. Macro name helloworld Visibility Visibl ...

  7. Android “Command” from work summary

    总结一下Android中的命令. 一.adb 与 shell ADB的全称为Android Debug Bridge(调试桥).是一个适用命令行工具,用来与模拟器实例或链接的Android设备进行通信 ...

  8. django的查看sql语句setting设置

    LOGGING = {     'version': 1,     'disable_existing_loggers': False,     'handlers': {         'cons ...

  9. Little Red Riding Hood

    问题 : Little Red Riding Hood 时间限制: 1 Sec  内存限制: 1280 MB 题目描述 Once upon a time, there was a little gir ...

  10. C++ GetSystemDirectory()

    关于GetSystemDirectory function,参考:https://msdn.microsoft.com/en-us/library/windows/desktop/ms724373(v ...