CodeForece 724C Ray Tracing 扩展欧几里得

Posted legend_PawN

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CodeForece 724C Ray Tracing 扩展欧几里得相关的知识,希望对你有一定的参考价值。

题目链接
题目的大意就是一束从(0,0)发出的光线经过有限次反射从一个矩形区域射出,在该矩形区域内布置有若干个传感器,试问光线第一次经过该传感器所需要的时间。
1.可以用模拟直接去做,模拟光线的反射,最后把每一个传感器的最小时间记录下来。
2.光线的反射,可以通过对称最后把有限次反射变换成直线通过。所以首先把矩阵左右,上下进行对称,我们可以知道最后光线射出的点为 (lcm(m,n),lcm(m,n))
同时,我们也将所有的传感器从单个矩阵的坐标映射到达的矩形区域内
(x,y)  (2pn±x,2qm±y)
如果光线经过传感器,就有 2pn±x=2qm±y ,得到以下四个不定方程组

2pm+x=2qm+y2pmx=2qm+y2pmx=2qmy2pm+x=2qmy
通过解这四个不定方程,找到最小的 2pm±x 就得到了经过传感器的最近时间。
AC代码:

#include <iostream>
#include <cstdio>
using namespace std;
typedef long long ll;
int n,m,k;
ll extend_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=extend_gcd(b,a%b,y,x);
    y-=a/b*x;
    return d;

ll gcd(ll a,ll b)
    return b==0 ? a : gcd(b,a%b);

ll equation(ll a, ll b,ll max)
    ll x,y;
    ll r=gcd(2*n,-2*m);
    if((b-a)%r)
        return max+1;
    extend_gcd(2*n/r,-2*m/r,x,y);
    x=x*(b-a)/r;
    y=y*(b-a)/r;
    ll g=2*m/r;
    if(g<0)
        g=-g;
    x=(x%g+g)%g;
    ll res=2*x*n+a;
    if(res<0 || res>max)
        return max+1;
    return res;

ll solve(ll a,ll b)
    ll lcm=1ll*m/gcd(m,n)*n;
    ll res=lcm+1;
    res=min(res,equation(a,b,lcm));
    res=min(res,equation(-a,b,lcm));
    res=min(res,equation(-a,-b,lcm));
    res=min(res,equation(a,-b,lcm));
    if(res==lcm+1)
        return -1;
    return res;

int main()
    //freopen("input.txt","r",stdin);
    while(~scanf("%d%d%d",&n,&m,&k))
        for(int i=1;i<=k;i++)
            ll a,b,ans=0;
            scanf("%lld%lld",&a,&b);
            ans=solve(a,b);
            printf("%lld\\n",ans);
        
    
    return 0;

以上是关于CodeForece 724C Ray Tracing 扩展欧几里得的主要内容,如果未能解决你的问题,请参考以下文章

CF724C: Ray Tracing

具有SUMO返回错误的Traci4J

codeforces 724C

codeforces 724C

SUMO1.9.2 TraCI python 简单使用

SUMO1.9.2 TraCI python 简单使用