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 就得到了经过传感器的最近时间。
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 扩展欧几里得的主要内容,如果未能解决你的问题,请参考以下文章