Codeforces Intel Code Challenge Final Round C.Ray Tracing

6 篇文章 0 订阅
4 篇文章 0 订阅

原题网址:http://codeforces.com/contest/724/problem/C
这1里写图片描述
如同做光学题时把物像翻折,这道题把点不断翻折,可得到一系列的点,就拿横坐标来说,翻折到得点横坐标依次为x,2na-x,2na+x,4na-x,4na+x,纵坐标对应的为y,2ma-y,2ma+y,4ma-y,4ma+y……
现在我们要找的是原来的点和翻折的“像”中横纵坐标相等的点,就得到了一个二元一次不定方程2na±x=2mb±y。按理说是要用拓展欧几里得做的,但这道题有一个优雅做法:将式子对2m取模,变为2na≡±x±y(mod 2m),对于2na=c(mod 2m)可以O(m)预处理出每个c对应取得的最小a。这样对于±x±y的值就可以在表中查到a,从而算出时间。
注意在等号一边取了减号的时候a≥1,所以3、4两种情况等式左边都有一个2n。

const
  INF=1<<60;
var
  f:array[0..200050] of int64;
  n,m,k,a,b:int64;
  i:longint;
  t,ans:int64;
function min(a,b:int64):int64;
  begin if (a<b) then exit(a) else exit(b); end;
function mode(x:int64):int64;
  begin exit((x mod (m<<1) + (m<<1)) mod (m<<1));end;
begin
  read(n,m,k);
  for i:=0 to m<<1 do f[i]:=-1;
  for i:=m<<1 downto 0 do
    f[(n*2*i) mod (m*2)]:=i;//预处理每个值对应的最小a
  for i:=1 to k do
    begin
      read(a,b);ans:=INF;
      t:=f[mode(-a+b)];
      if (t<>-1) then ans:=min(ans,t*n*2+a);
      t:=f[mode(-a-b)];
      if (t<>-1) then ans:=min(ans,t*n*2+a);
      t:=f[mode(+a-n<<1+b)]; 
      if (t<>-1) then ans:=min(ans,(t+1)*n*2-a);
      t:=f[mode(+a-n<<1-b)]; 
      if (t<>-1) then ans:=min(ans,(t+1)*n*2-a);
      if (ans=INF) then ans:=-1;
      writeln(ans);
    end;
end.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值