hdu 5114 Collision 扩展欧几里得

题目链接

题意 先给出一个矩形的范围a,b,然后给出两个点的坐标,这两个点都以速度(1,1)移动

碰到矩形边时 以(-1,-1)移动再循环往复,两个点相碰撞时的坐标。

可以将速度分解,直接求时间,可以分为四种情况

第一种x1==x2&&y1==y2

这时两个点已经碰撞 所以tc=0

第二种x1==x2&&y1!=y2

只需判断什么时候y相等 推出公式tc=ty=b-(y1+y2)/2;

第三种x1!=x2&&y1==y2

只需判断什么时候y相等 推出公式tc=tx=a-(x1+x2)/2;

第四种 x1!=x2&&y1!=y2

tc=tx+a*T1;

tc=ty+b*T2

T1*a+T2*b=gcd(T1,T2) 扩欧

处理一下就得到结果啦 注意x要取最小的

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
typedef long long ll;
ll x,y;
ll ex_gcd(ll a,ll b,ll &x,ll &y)
{
    if(b==0)
    {
        x=1,y=0;
        return a;
    }
    ll ret=ex_gcd(b,a%b,y,x);
    y-=a/b*x;
    return ret;
}
ll gcd(ll a,ll b)
{
    return b==0?a:gcd(b,a%b);
}
int main()
{
    int t,d;
    cin>>t;
    int fgh=1;
    while(t--)
    {
        ll a,b,x1,y1,x2,y2;
        cin>>a>>b;
        cin>>x1>>y1>>x2>>y2;
        a*=2;
        b*=2;
        x1*=2;
        y1*=2;
        x2*=2;
        y2*=2;
        ll ansx=-1,ansy=-1,tx,ty,tc=-1;
        tx=a-(x1+x2)/2;
        ty=b-(y1+y2)/2;
        printf("Case #%d:\n",fgh++);
        if(x1==x2)
        {
            if(y1==y2)
            {
                tc=0;
            }
            else
            {
                tc=ty;
            }
        }
        else if(y1==y2)
        {
            if(x1==x2)
            {
                tc=0;
            }
            else
            {
                tc=tx;
            }
        }
        else
        {
            ex_gcd(a,b,x,y);
            d=gcd(a,b);
            if((ty-tx)%d==0)
            {
                x=(ty-tx)/d*x;
                x=(x%(b/d)+b/d)%(b/d);
                tc=(tx+a*x);
            }
        }
        ansx=(x2+tc)%(a*2);
        ansy=(y2+tc)%(b*2);
        if(ansx>a)
            ansx=2*a-ansx;
        if(ansy>b)
            ansy=2*b-ansy;
        if(tc==-1)
            puts("Collision will not happen.");
        else
            printf("%.1lf %.1lf\n",ansx/2.0,ansy/2.0);
    }

    return 0;
}



猜你喜欢

转载自blog.csdn.net/yangdelu855/article/details/79089032