zoukankan      html  css  js  c++  java
  • HDU 5114 Collision(扩展欧几里得) xgtao

    Collision

    给出l*w的球桌,再给出球桌上的两个球(x1,y1)(x2,y2),分别以(1,1)的速度进行运动,问他们第一次碰撞的坐标。

    首先将速度进行正交分解,分解成沿水平的方向1和沿竖直的方向1:

    第一种情况:

    第二种情况:

    T = 2*l-(x1+x2)/2+2nl;

    T = l-(x1+x2)/2+2nl;

    合并得到:T = nl-(x1+x2)/2;

    同理得到:T = n'w-(y1+y2)/2;

    然后nl-n'w = (x1+x2)/2-(y1+y2)/2,由扩展欧几里得解出n,n',求出n最小解然后解出T,然后坐标+T mod 2*l,如果坐标>l,就用2*l-l,就求出x,y;

    #include <cstdio>
    #include <iostream>
    #include <cstring>
    #include <algorithm>
    #define eps 1e-6
    #define LL long long
    using namespace std;
    
    //T = k1l-(x1+x2)/2
    //T = k2w-(y1+y2)/2
    //lk1-wk2 = (x1+x2)/2-(y1+y2)/2
    
    void exgcd(LL a,LL b,LL &gcd,LL &x,LL &y){
    	if(!b){gcd = a;x = 1;y = 0;}
    	else{exgcd(b,a%b,gcd,y,x);y -= x*(a/b);}
    }
    
    double ansx,ansy,tt;
    int r,kase,l,w,x,y,xx,yy;
    LL gcd,k1,k2;
    
    int main(){
    	scanf("%d",&r);
    	for(int kase = 1;kase <= r;++kase){
    		printf("Case #%d:\n",kase);
    		scanf("%d%d",&l,&w);
    		scanf("%d%d%d%d",&x,&y,&xx,&yy);
    		if(x == xx && y == yy){printf("%.1lf %.1lf\n",1.0*x,1.0*y);continue;}
    		if(x == xx){
    			tt = w-1.0*(y+yy)/2.0;
    			ansy = y+tt>w?2*w-y-tt:y+tt;
    			ansx = x+tt>l?2*l-x-tt:x+tt;
    			printf("%.1lf %.1lf\n",ansx,ansy);
    			continue;
    		}
    		if(y == yy){
    			tt = l-1.0*(x+xx)/2.0;
    			ansx = x+tt>l?2*l-x-tt:x+tt;
    			ansy = y+tt>w?2*w-y-tt:y+tt;
    			printf("%.1lf %.1lf\n",ansx,ansy);
    			continue;
    		}
    		LL p = x+xx-y-yy;
    		if(p%2 != 0){puts("Collision will not happen.");continue;}
    		p >>= 1;
    		LL a = l,b = -w;
    		exgcd(a,b,gcd,k1,k2);
    		if(p%gcd != 0){puts("Collision will not happen.");continue;}
    		
    		k1 = p/gcd*k1;
    		LL z = k1/(w/gcd);
    		k1 -= w/gcd*z;  
            if(k1<1) k1 += abs(w/gcd); //最小正整数解 
            
    		tt = k1*l-1.0*(xx+x)/2.0;
    		LL c = (x+tt)/(2*l+eps);
    		double tx = x+tt-2.0*l*c;
    		c = (y+tt)/(2*w+eps);
    		double ty = y+tt-2.0*c*w;
    		ansx = tx>l?2*l-tx:tx;
    		ansy = ty>w?2*w-ty:ty;
    		printf("%.1lf %.1lf\n",ansx,ansy);
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    引爆点--产品方法论
    智能的差旅预订 竞品分析
    差旅管理
    运营中的用户心理学
    鸡汤
    励志的鸡汤
    cmder安装
    jQuery height() innerHeight() outerHight() width() innerWidth() outerWidth()源码解读
    css未知宽度水平居中整理
    css水平垂直居中块整理
  • 原文地址:https://www.cnblogs.com/xgtao984/p/5681964.html
Copyright © 2011-2022 走看看