您的位置:首页 > 其它

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了。

源码:

#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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: