HDU 5114 思维 + 数论
2015-10-26 20:50
309 查看
HDU 5114
题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=5114
题意:
两个球在一个矩形里面做完全弹性碰撞的运动,位置给出,速度恒为(1,1)。
问它们会不会碰撞到一起,会的话第一次碰撞在哪个点?
思路:
首先这种碰撞问题有一个固定模型就是将速度进行正交分解。然后很轻易发现同时满足(x1+x2+t+t)%x = 0 和 (y1 + y2 + t + t)%y = 0时条件成立。
讨论四种情况,主要看下第四种,其他的应该很容易想出来。
然后这是一个同余方程,用扩展欧几里得就可以。
但是题目有坑点,那就是在满足上面那个条件的同时还要满足(x1+t)/n%2 != (x2+t)/n%2,具体的话就是即使两个坐标之和为长方形的长度,它们速度相等也是不对的。所以上面的方程要改成(x1+x2+t+t)%(2*x)和(y1+y2+t+t)%(2*y)。
这题数据卡的比较紧,中间求时间那里没有求余就WA了。
源码:
题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=5114
题意:
两个球在一个矩形里面做完全弹性碰撞的运动,位置给出,速度恒为(1,1)。
问它们会不会碰撞到一起,会的话第一次碰撞在哪个点?
思路:
首先这种碰撞问题有一个固定模型就是将速度进行正交分解。然后很轻易发现同时满足(x1+x2+t+t)%x = 0 和 (y1 + y2 + t + t)%y = 0时条件成立。
讨论四种情况,主要看下第四种,其他的应该很容易想出来。
然后这是一个同余方程,用扩展欧几里得就可以。
但是题目有坑点,那就是在满足上面那个条件的同时还要满足(x1+t)/n%2 != (x2+t)/n%2,具体的话就是即使两个坐标之和为长方形的长度,它们速度相等也是不对的。所以上面的方程要改成(x1+x2+t+t)%(2*x)和(y1+y2+t+t)%(2*y)。
这题数据卡的比较紧,中间求时间那里没有求余就WA了。
源码:
#include <cstdio> #include <cstring> #include <cmath> #include <cstdlib> #include <algorithm> #include <iostream> #include <string> using namespace std; #define LL long long LL gcd(LL a, LL b, LL &x, LL &y) { if(a < 0) return gcd(-a, -b, x, y); if(b == 0){ x = 1, y = 0; return a; } LL d = gcd(b, a % b, y, x); y -= a / b * x; return d; } int main() { int t; scanf("%d", &t); for(int cas = 1 ; cas <= t ; cas++){ LL x, y; scanf("%I64d%I64d", &x, &y); LL x1, y1, x2, y2; scanf("%I64d%I64d%I64d%I64d", &x1, &y1, &x2, &y2); LL k1, k2; x1 *= 2, x2 *= 2, y1 *= 2, y2 *= 2, x *= 2, y *= 2; LL d = gcd(x, y, k1, k2); printf("Case #%d:\n", cas); double ansx, ansy; if(x1 == x2 && y1 == y2){ ansx = x1, ansy = y1; printf("%.1f %.1f\n", ansx / 2, ansy / 2); } else if(x1 == x2){ int temp = (2 * y - y1 - y2) / 2; ansx = (x1 + temp) % (2 * x); if(ansx > x) ansx = 2 * x - ansx; ansy = (y1 + temp) % (2 * y); if(ansy > y) ansy = 2 * y - ansy; printf("%.1f %.1f\n", ansx / 2, ansy / 2); } else if(y1 == y2){ int temp = (2 * x - x1 - x2) / 2; ansx = (x1 + temp) % (2 * x); if(ansx > x) ansx = 2 * x - ansx; ansy = (y1 + temp) % (2 * y); if(ansy > y) ansy = 2 * y - ansy; printf("%.1f %.1f\n", ansx / 2, ansy / 2); } else if(((x1 + x2 - y1 - y2) / 2) % d != 0){ printf("Collision will not happen.\n"); continue; } else{ LL k = ((x1 + x2 - y1 - y2) / 2 / d); if(k1 < 0) k1 += y / d; LL temp = k1 * x * k - (x1 + x2) / 2; k = (x * y) / d; temp = temp % k; if(temp < 0) temp = (temp % k + k) % k; ansx = (x1 + temp) % (2 * x); if(ansx >= x) ansx = 2 * x - ansx; ansy = (y1 + temp) % (2 * y); if(ansy >= y) ansy = 2 * y - ansy; // if((x1 + temp) / x % 2 == 0) ansx = (x1 + temp) % x; // else ansx = ((x - x1 - temp) % x + x) % x; // if((y1 + temp) / y % 2 == 0) ansy = (y1 + temp) % y; // else ansy = ((y - y1 - temp) % y + y) % y; printf("%.1f %.1f\n", ansx / 2.0, ansy / 2.0); } } return 0; }
相关文章推荐
- 第9周项目1 - 猴子选大王(数组版)
- 博主自荐
- 中国大学MOOC-陈越、何钦铭-数据结构 File Transfer
- Java中的设计模式
- POJ 题目1915 Knight Moves(双向BFS)
- Xcode6 升级Xcode7 推送出的错误
- [Ioi2005]River
- 两个字符窜,在母窜中查找子窜的位置
- ubuntu12.04TLS安装CodeBlocks
- TDA线程分析初步
- linux下安装python后无法执行错误解决
- android实现超链接的3中方法
- OC第一天:类和对象
- ANDROID OKHTTP MVP
- 对称矩阵的压缩存储及基本运算(1)
- 黑马程序员****C语言基础****C语言的基本概念
- System.DllNotFoundException Unable to load DLL SQLite.Interop.dll解决办法
- 顶层const与底层const
- C#中登录界面常用方法,回车键直接登录
- 文件系统fsd hook (一)原理