HDU 5114 思维 + 数论
来源:互联网 发布:淘宝直通车开通怎么用 编辑:程序博客网 时间:2024/05/17 23:30
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了。
源码:
#include <cstdio>#include <cstring>#include <cmath>#include <cstdlib>#include <algorithm>#include <iostream>#include <string>using namespace std;#define LL long longLL 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;}
0 0
- HDU 5114 思维 + 数论
- 【HDU】5776 - sum(数论 & 思维)
- 【hdu 6069】 Counting Divisors 【思维+数论】
- hdu 5812 Distance 数论+思维枚举
- HDU ACM 4473 Exam->数论(思维-问题转换)
- HDU 5288 OO’s Sequence (数论 + 思维)
- 吃糖果 hdu 1205 数论中思维问题 鸽巢原理
- hdu 5171 GTY's birthday gift【矩阵快速幂】【思维】【感受矩阵和数论的神奇】
- HDU --- 5446 Unknown Treasure 数论综合【Lucas定理 + 中国剩余定理 + 快速乘 + 思维】
- AtCoder:11(数论 & 思维)
- HDU 2204 (数论)
- 数论 MillerRabin hdu 3792
- HDU 3123 数论
- 【数论】HDU-4196-Remoteland
- HDU 3988 数论
- HDU 1787 数论
- hdu 1395 数论
- HDU 2104数论 欧几里得
- android实现超链接的3中方法
- C语言冒泡排序
- 中国大学MOOC-陈越、何钦铭-数据结构 File Transfer
- Java中的设计模式
- 博主自荐
- HDU 5114 思维 + 数论
- iOS9 HTTP访问不了的解决方法
- HDU-2159(FATE)
- 20151026-linux目录操作
- Linux-CentOS XAMPP Apache配置多端口
- UVALive 6462 状压DP
- Remove Duplicates from sorted array
- 旋转数组中的最小数字
- oracle dba 使用mysql 时的痛点--待吐槽