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萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章