zoukankan      html  css  js  c++  java
  • Ray Tracing

    Ray Tracing

    题目链接:http://codeforces.com/problemset/problem/724/C

    拓展欧几里得

    //为什么这次C题这么难啊=。=

    可以观察到,光线在矩形中运动的时间为LCM(n,m),所以可以把整个矩阵扩展成LCM(n,m)*LCM(n,m)的矩阵[光线从(0,0)点一直射到(LCM(n,m),LCM(n,m))点],然后将点关于矩形的四条边变换到直线y=x上,取最小的即可。

    变换后得到的点的纵坐标为2*p*n±X,横坐标为2*q*m±Y,因为要求在直线y=x上,故2*p*n±X=2*q*m±Y,移项得2*p*n-2*q*m=±X±Y。

    而拓展欧几里得可以解不定方程a*x+b*y=c,其中c=GCD(a,b),令a=2*n,b=-2*m,求得x和y。

    将方程a*x+b*y=c变换成2*p*n-2*q*m=±X±Y,得到p或q,求出2*p*n±X或2*q*m±Y即可。

    //注意求得的p或q要为自然数

    代码如下:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include <cmath>
     4 using namespace std;
     5 typedef long long LL;
     6 const LL INF=100000000000000000;
     7 LL GCD(LL a,LL b){
     8     return b==0?a:GCD(b,a%b);
     9 }
    10 LL exGCD(LL a,LL b,LL &x,LL &y){
    11     if(b==0){
    12         x=1,y=0;
    13         return a;
    14     }
    15     LL t=exGCD(b,a%b,x,y);
    16     LL r=x;x=y;y=r-a/b*y;
    17     return t;
    18 }
    19 LL LCM(LL a,LL b){
    20     LL gcd=GCD(a,b);
    21     return (a/gcd)*b;
    22 }
    23 LL n,m,k,x,y,p,q,a,b,lim,mul;
    24 LL mix(LL x,LL y){
    25     LL t=x-y;
    26     if(t%mul!=0)return INF;
    27     t/=mul;
    28     p=a*t;
    29     LL mod=abs((-2*m)/mul);//mod is the t of p*x*t-q*y*t=gcd*t
    30     p=(p%mod+mod)%mod;
    31     LL tmp=INF;
    32     LL tt=2*n*p-x;
    33     if(0<tt&&tt<=lim)tmp=min(tmp,tt);
    34     return tmp;
    35 }
    36 int main(void){
    37     scanf("%I64d%I64d%I64d",&n,&m,&k);
    38     lim=LCM(n,m);
    39     for(LL i=0;i<k;++i){
    40         scanf("%I64d%I64d",&x,&y);
    41         mul=exGCD(2*n,-2*m,a,b);
    42         //mul=GCD(2*n,-2*m);
    43         LL ans=INF;
    44         ans=min(ans,mix(-x,y));
    45         ans=min(ans,mix(x,y));
    46         ans=min(ans,mix(-x,-y));
    47         ans=min(ans,mix(x,-y));
    48         if(ans<INF)printf("%I64d
    ",ans);
    49         else printf("-1
    ");
    50     }
    51 }
  • 相关阅读:
    Ubuntu 部署 nginx
    Arduino使用HC05蓝牙模块与手机连接
    Bootstrap 简介
    微信小程序新闻列表功能(读取文件、template模板使用)
    微信小程序编写新闻阅读列表
    编写第一个微信小程序界面
    微信小程序开发环境
    了解微信小程序
    jQuery 选择器
    jQuery API的特点
  • 原文地址:https://www.cnblogs.com/barrier/p/5943844.html
Copyright © 2011-2022 走看看