传送门

Matt is playing a naive computer game with his deeply loved pure girl.

The playground is a rectangle with walls around. Two balls are put in different positions inside the rectangle. The balls are so tiny that their volume can be ignored. Initially, two balls will move with velocity (1, 1). When a ball collides with any side of the rectangle, it will rebound without loss of energy. The rebound follows the law of refiection (i.e. the angle at which the ball is incident on the wall equals the angle at which it is reflected).

After they choose the initial position, Matt wants you to tell him where will the two balls collide for the first time.

Input
The first line contains only one integer T which indicates the number of test cases.

For each test case, the first line contains two integers x and y. The four vertices of the rectangle are (0, 0), (x, 0), (0, y) and (x, y). (1 ≤ x, y ≤ 10 5)

The next line contains four integers x 1, y 1, x 2, y 2. The initial position of the two balls is (x 1, y 1) and (x 2, y 2). (0 ≤ x 1, x 2 ≤ x; 0 ≤ y 1, y 2 ≤ y)

Output
For each test case, output “Case #x:” in the first line, where x is the case number (starting from 1).

In the second line, output “Collision will not happen.” (without quotes) if the collision will never happen. Otherwise, output two real numbers x c and y c, rounded to one decimal place, which indicate the position where the two balls will first collide.

Sample Input
  
3
10 10
1 1 9 9
10 10
0 5 5 10
10 10
1 0 1 10
Sample Output
  
Case #1:
6.0 6.0
Case #2:
Collision will not happen.
Case #3:
6.0 5.0
Hint

In first example, two balls move from (1, 1) and (9, 9) both with velocity (1, 1), the ball starts from (9, 9) will rebound at point (10, 10) then move with velocity (−1, −1). The two balls will meet each other at (6, 6).

题目大意:

给了一个 x∗y x*y 的矩阵,在这个矩阵中有两个小球(体积可以忽略):小球1 (x1,y1) (x_1,y_1), 小球2 (x2,y2) (x_2,y_2) 现在这两个小球都以 (1,1) (1,1) 的速度在运动,如果碰到边界会发生反弹(不损失能量),现在求两个小球第一次碰撞时的坐标。

解题思路:

我们可以将这个小球的运动在 x x 轴 和 yy 轴上进行分解,在 x x 轴上是匀速直线运动,同理在 yy 轴上也是匀速直线运动。现在小球1 和 小球2 的坐标有四种情况:
1) x1=x2 and y1=y2 x_1=x_2 \ and\ y_1=y_2
2) x1=x2 and y1≠y2 x_1=x_2 \ and\ y_1\ne y_2
3) x1≠x2 and y1=y2 x_1\ne x_2 \ and\ y_1=y_2
4) x1≠x2 and x1≠y2 x_1\ne x_ 2 \ and\ x_1\ne y_2
现在就四种情况分别进行讨论:
如果是第一种情况的话,第一次碰撞的点就是 (x1,y1) || (x2,y2) (x_1,y_1)\ ||\ (x_2,y_2)
如果是第二种情况的话,我们首先设在第一次碰撞的时间为 ty t_y,第一次碰撞的点为 (xp,yp) (x_p, y_p)
那么就有 下图所示方程成立:

更正:对于图中的第二个式子有错误,应该是: ty=yp−y1 t_y=y_p-y_1

然后可以解得: ty = (2∗y−(y1+y2))2 t_y\ =\ \frac {(2*y-(y_1+y_2))}2,然后 (xp,yp) (x_p,y_p) 就能确定了
同理,如果是第三种情况的话,我们可以解出 tx = (2∗x−(x1+x2))2 t_x\ =\ \frac {(2*x-(x_1+x_2))} 2, 然后 (xp,yp) (x_p,y_p) 也能确定了
如果是第四种情况的话就只需要加上一个周期就行了,对于 x x 轴来说,
tx = (2∗x−(x1+x2))2+a∗x  a:表示经过a个周期,周期为 xt_x\ =\ \frac {(2*x-(x_1+x_2))} 2+a*x\ \ a:表示经过a个周期,周期为\ x
ty = (2∗y−(y1+y2))2+b∗y  b:表示经过b个周期,周期为 y t_y\ =\ \frac {(2*y-(y_1+y_2))} 2+b*y\ \ b:表示经过b个周期,周期为\ y
然后又因为 tx = ty t_x\ =\ t_y, 然后联力两个方程组得到如下方程:
(2∗x−(x1+x2))2+a∗x=(2∗y−(y1+y2))2+b∗y \frac {(2*x-(x_1+x_2))} 2+a*x=\frac {(2*y-(y_1+y_2))} 2+b*y
移项得:
a∗x−b∗y=(2∗y−(y1+y2))2−(2∗x−(x1+x2))2 a*x-b*y=\frac {(2*y-(y_1+y_2))} 2-\frac {(2*x-(x_1+x_2))} 2

这就是我们所常见的一元二次方程,然后扩展欧几里得一下求得 a a 的最小正整数解就 OK 了。
需要注意的是,这里有一个小 trick:因为方程里有除法操作,所以我们先把所有的变量乘以 2,然后在操作就行了,还有就是 如果最后求得的解如果大于 xx 或者 y <script type="math/tex" id="MathJax-Element-480">y</script> 的话,就是反弹了,然后减一下就行,具体看代码。
代码:

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
inline LL GCD(LL a, LL b){if(b == 0) return a;return GCD(b, a%b);
}
void Exgcd(LL a, LL b, LL &x, LL &y){if(b == 0){x = 1, y = 0;return;}LL x1, y1;Exgcd(b, a%b, x1, y1);x = y1;y = x1 - (a/b)*y1;
}
int main()
{int T; scanf("%d", &T);for(int cas=1; cas<=T; cas++){LL x, y, x1, x2, y1, y2;scanf("%lld%lld%lld%lld%lld%lld", &x, &y, &x1, &y1, &x2, &y2);x<<=1, y<<=1, x1<<=1, y1<<=1, x2<<=1, y2<<=1;printf("Case #%d:\n",cas);LL tx = (2*x-(x1+x2))/2, ty = (2*y-(y1+y2))/2;if(x1==x2 && y1==y2) printf("%.1f %.1f\n", 0.5*x1, 0.5*y1);else if(x1 == x2){if(y1 > y2) swap(y1, y2);x1 = (x1+ty)%(2*x), y1 = (y1+ty)%(y*2);if(x1 > x) x1 = 2*x - x1;if(y1 > y) y1 = 2*y - y1;printf("%.1f %.1f\n", 0.5*x1, 0.5*y1);}else if(y1 == y2){if(x1 > x2) swap(x1, x2);x1 = (x1+tx)%(2*x), y1 = (y1+tx)%(y*2);if(x1 > x) x1 = 2*x - x1;if(y1 > y) y1 = 2*y - y1;printf("%.1f %.1f\n", 0.5*x1, 0.5*y1);}else{LL tp = ty - tx;LL d = GCD(x, y);if(tp % d) puts("Collision will not happen.");else{LL a = x / d, b = y / d, c = tp / d, xx;Exgcd(a, b, xx, ty);xx *= c;xx = (xx%b+b)%b;tx = tx + x*xx;x1 = (x1+tx)%(2*x), y1 = (y1+tx)%(y*2);if(x1 > x) x1 = 2*x - x1;if(y1 > y) y1 = 2*y - y1;printf("%.1f %.1f\n", 0.5*x1, 0.5*y1);}}}return 0;
}

HDU 5514 Collision(扩展欧几里得+解方程)——2014ACM/ICPC亚洲区北京站相关推荐

  1. CodeForces - 724C Ray Tracing(扩展欧几里得解方程)

    题目链接:点击查看 题目大意:在 n∗mn*mn∗m 的矩阵中,从点 (0,0)(0,0)(0,0) 发射一个小球,以四十五度的方向出发,速度是 2\sqrt{2}2​,当碰到壁时,会进行反射:当碰到 ...

  2. 扩展欧几里得 解方程小记

    本来以前学习的时候就懵懵懂懂,长时间不用就完全不会了.. 首先对于扩展欧几里得,对于最一般的方程形式 ax+by=gcd(a,b),此方程一定有整数解,扩展欧几里便得能够求出其中的一组整数解x0,y0 ...

  3. qdu 2017级纳新题(扩展欧几里得)

    在你面前撒个娇 哎呦喵喵喵喵喵 Description 我们一起学猫叫 一起喵喵喵喵喵 在你面前撒个娇 哎呦喵喵喵喵喵 我的心脏砰砰跳 迷恋上你的坏笑 你不说爱我我就喵喵喵 每当xjy和hqy一起唱起 ...

  4. 欧几里得算法扩展欧几里得

    本文包括: 1.几里德算法 递归实现 2.扩展欧几里德算法 递归实现 -实际上就是把别人总结的,我认为有助于自己理解的内容copy过来,再加上几句自己的理解. 欧几里得算法 欧几里德算法又称辗转相除法 ...

  5. 扩展欧几里得 POJ 1061

    感觉这道题目的数据好水啊...我的代码我都觉得姿势特别奇怪...竟然还过了... 好吧,原来不是姿势奇怪,而是逆元需要用的时候是余数也需要的时候,这里的余数是不需要的,所以就AC了 就说一下碰到的问题 ...

  6. 求逆元(线性求逆元)及其扩展欧几里得

    线性求逆元模板: int inv[maxn]; void initInverse(){inv[1] = 1;for(int i = 2; i <= maxn; i++)inv[i] = (p - ...

  7. poj-青蛙的约会(扩展欧几里得)nyoj-小柯的约会

    由题意可列出方程 x + m * s - (y + n * s) = k * l; 化简得   (n-m)*s + k*l = x - y 化简得   (n-m)*s = x - y (mod l); ...

  8. [模板]欧几里得算法/扩展欧几里得

    最大公因数(欧几里得算法) $gcd(a,b)=gcd(b\%a,a)$(不一定需要a<b) $gcd(0,b)=b$ 1 inline int gcd(int a,int b){ 2 retu ...

  9. “景驰科技杯”2018年华南理工大学程序设计竞赛 H-对称与反对称(扩展欧几里得求逆元)

    题目链接 题目描述: 给出一个N*N的方阵A.构造方阵B,C: 使得A = B + C.其中 B为对称矩阵,C为反对称矩阵. 对于方阵S中的任意元素,若(S)ij = (S)ji,则称S为对称矩阵 对 ...

最新文章

  1. 三菱fx2n64mr说明书_三菱FX2N可编程控制器使用手册
  2. c语言断链隐藏dll,通过断链隐藏模块(DLL)
  3. 11g中AWR新快照视图
  4. 根据根据图片的url怎么取得图片ImageView对象
  5. php隐藏做上传图片,php做图片上传功能
  6. oracle雇主联盟官网,ocm联盟线下分享会圆满结束!
  7. matlab-高数 meshgrid 笛卡尔乘积(直积)
  8. 移动硬盘测试扩容卡软件,U盘扩容检测教程,优盘容量真实性检测,TF卡移动硬盘SD卡内存卡...
  9. 桌面总是弹出计算机内存不足,Win10提示计算机的内存不足请保存文件并关闭这些程序怎么办...
  10. 车间图纸管理软件-车间无纸化管理解决方案
  11. 前端学习笔记之品优购项目(一) 3.15
  12. web前端工程师岗位职责和要求
  13. android中一些特殊字符的使用(如:←↑→↓等箭头符号)
  14. 2021年教你如何用笔记本把Windows10系统安装到移动固态硬盘或U盘简易教程
  15. 机器学习--单细胞聚类(二)
  16. ESLint语法检查
  17. 5年 Android 面试题
  18. LaTeX插入矩阵和方程组
  19. 怎样去掉“交互式服务对话框检测”提示对话框
  20. github汉化注意事项(Chrome)

热门文章

  1. 云原生是什么?云原生最近又火了
  2. matlab提取矩阵数据:行、列、块
  3. SystemTap Beginner
  4. 贪心算法之贪心的c小加问题
  5. 计算机图形学 - surface,layer,pipeline
  6. 例题 4-1 古老的密码(Ancient Cipher) UVa 1339
  7. 宝塔linux面板 h5ai,宝塔面板丨Nginx环境下H5ai(Dplayer)完整安装使用教程及注意事项...
  8. c语言编程10000次模拟抛硬币,用c语言模拟抛硬币的过程
  9. 清明梦超能力者黄YY(idx数组)
  10. 软件测试8年,却被应届生踩在头上,是应届生太牛了,还是我们太弱了?