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
原创粉丝点击