Collision (hdu-5114

  题意:你有一个以(0, 0), (x, 0), (0, y), (x, y)为边界点的四边形,给你两个点从(x1, y1), (x2, y2)的点发射,以(1, 1)的速度走,碰到边界会反射,问你最终两个点在什么地方相遇。

  分析:点有三种情况

    A.两点重合

      直接输出坐标

    B.只有x轴或者y轴相等。

      以y轴相等,x1>x2为例。当他们重合时X=n-(x1+t-n), X=x2+t。此时求出t=n-(x1+x2)/2,知道t后,很容易就知道答案。

    C.x轴y轴都不相等

      其实可以知道x轴相遇的话是以n为周期,y轴相遇是以m为周期<其实我不知道,后面看了他们的我才知道>。

      t = n-(x1+x2)/2+a*n

      t = m-(y1+y2)/2+b*m

      那么用扩展欧几里得就可以求出来了。

ll n, m;

ll e_gcd(ll a,ll b,ll &x,ll &y)  {
    if(b==0)
    {
        x=1;
        y=0;
        return a;
    }
    ll ans=e_gcd(b,a%b,x,y);
    ll temp=x;
    x=y;
    y=temp-a/b*y;
    return ans;
}

void solve() {
    scanf("%lld%lld", &n, &m);
    ll x1, x2, y1, y2;
    scanf("%lld%lld%lld%lld", &x1, &y1, &x2, &y2);
    n*=2, m*=2, x1*=2, y1*=2, x2*=2, y2*=2;
    ll tim=-1;
    ll ta = n-(x1+x2)/2, tb = m-(y1+y2)/2;
    if (x1==x2&&y1==y2) {
        tim = 0;
    }
    if (x1==x2&&y1!=y2) {
        tim = tb;
    }
    if (x1!=x2&&y1==y2) {
        tim = ta;
    }
    if (x1!=x2&&y1!=y2) {
        ll x, y;
        ll d=e_gcd(n, m, x, y);
        if ((tb-ta)%d==0) {
            x = (tb-ta)/d*x;
            x = (x%(m/d)+m/d)%(m/d);
            tim = ta+x*n;
        }
    }
    if (tim==-1) {
        printf("Collision will not happen.
");
    }
    else {
        ll x=(x1+tim)%(2*n), y=(y1+tim)%(2*m);
        if (x>n)  x = 2*n-x;
        if (y>m)  y = 2*m-y;
        printf("%.1f %.1f
", x/2.0, y/2.0);
    }
}
int main() {
    int t=1;
    //freopen("in.txt", "r", stdin);
    scanf("%d", &t);
    for (int T=1; T<=t; T++) {
        printf("Case #%d:
", T);
        solve();
    }
    return 0;
}
原文地址:https://www.cnblogs.com/gggyt/p/7880993.html