hdu5114 Collision(一元同余方程)

推了一晚上,还是没发现问题会转化成同余方程。
为了避免小数,所有点座标*2
对于这种题,感觉应先考虑一维的情况,
x1,x2,[0,x0],方向1
那么if x1==x2,就直接相撞
else 设移动tx步
不妨对x2做对称,则x2变为2k*x0-x2,此时方向为-1
则 x1+1* tx=2k* x0-x2+(-1)* tx
即 tx=k*x0-(x1+x2)/2
tx的最小值就是x0-(x1+x2)/2
同理知,
ty=y0-(y1+y2)/2
所以当x1==x2&&y1==y2,直接输出当前位置
当x1==x2&&y1!=y2 ,就退化成了一维
当x1!=x2&&y1!=y2,
那么问题就是求k1,k2满足
tx+k1* x0==ty+k2* y0,即k1* x0==(ty-tx)%y0
(求的时候记得先x=x*(ty-tx)/d,x%=(y/d),别弄反了)
求出后应移动的步数tt就等于tx+k1*x0
然后(x1+tt,y1+tt)就是可能的答案,因为它有可能不在[0,x0] * [0,y0]内,
(修改地方:)
当x1+tt是x0的倍数的时候,看它是x0的奇数倍还是偶数倍,若是奇数倍,ans=x0;否则ans=0.
当x1+tt在((n-1)x0,n * x0) (n为奇数) ans=(x1+tt)%x0
(n为偶数) ans=((x0-x1-tt)%x0+x0)%x0
算出的答案记得还要再除以2.0

#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <stdlib.h>
#include <stack>
#include <vector>
#include <string.h>
#include <queue>
#define msc(X) memset(X,-1,sizeof(X))
#define ms(X) memset(X,0,sizeof(X))
typedef long long LL;
using namespace std;
LL ex_gcd(LL a,LL b,LL &x,LL &y)
{
    if(a==0&&b==0) return -1;
    if(b==0) {x=1;y=0;return a;}
    LL d=ex_gcd(b,a%b,y,x);
    y-=a/b*x;
    return d;
}
int main(int argc, char const *argv[])
{
    int t,ti=0;
    scanf("%d",&t);
    while(++ti<=t){
        int xx0,yy0,xx1,yy1,xx2,yy2;
        scanf("%d%d%d%d%d%d",&xx0,&yy0,&xx1,&yy1,&xx2,&yy2);
        xx0<<=1,yy0<<=1,xx1<<=1,yy1<<=1,xx2<<=1,yy2<<=1;
        LL tx=xx0-(xx1+xx2)/2,ty=yy0-(yy1+yy2)/2;
        printf("Case #%d:\n",ti );
        if(xx1==xx2&&yy1==yy2) printf("%.1f %.1f\n",xx1/2.0,yy1/2.0 );
        else{
                LL tt=-1;
                if(xx1==xx2) tt=ty;
                else if(yy1==yy2) tt=tx;
                else {
                    LL x,y;
                    LL d=ex_gcd(xx0,yy0,x,y);
                    if((ty-tx)%d==0){
                        LL k1=(ty-tx)/d*x;
                        k1=(k1%(yy0/d)+yy0/d)%(yy0/d);
                        tt=tx+k1*xx0;
                        }
                }
                if(tt==-1) puts("Collision will not happen.");
                else{
                    LL ax=xx1+tt,ay=yy1+tt;
                    if(ax%xx0==0) {
                        if((ax/xx0)%2) ax=xx0;
                        else ax=0;
                    }
                    else if((ax/xx0)%2) 
                        ax=((xx0-ax)%xx0+xx0)%xx0;
                    else ax=(ax%xx0+xx0)%xx0;
                    if(ay%yy0==0){
                        if((ay/yy0)%2) ay=yy0;
                        else ay=0;
                    }
                    else if((ay/yy0)%2) 
                        ay=((yy0-ay)%yy0+yy0)%yy0;
                    else ay=(ay%yy0+yy0)%yy0;
                    printf("%.1f %.1f\n",ax/2.0,ay/2.0 );
                }
            }
    }
    return 0;
}
发布了110 篇原创文章 · 获赞 3 · 访问量 3万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章