yukicoder No.321 - (P,Q)-サンタと街の子供たち

Source

ニコニコミュニティ
問題文

問題概要

非負整数 $P,Q$ と二次元平面上の $N$ 個の格子点 $(X_1,Y_1), (X_2,Y_2), \ldots, (X_N,Y_N)$ が与えられる.
最初原点にいて,$(x,y)$ にいるとき,$|x-x'|=P,\;|y-y'|=Q$ または $|x-x'|=Q,\;|y-y'|=P$ なる $(x', y')$ に移動することができる.
$N$ 個の点のうち,何個の点に辿り着けるかを求める問題.

解法

まず,$P=Q=0$ の時は,原点のみ辿り着けるので,それは例外処理する.
$g = \mathrm{GCD}(P,Q)$ とすると(ただし $\mathrm{GCD}(0,n)=n$ とする)$x$ 座標も $y$ 座標も $g$ の倍数となる点以外は辿り着けないのは明らか.
よって,明らかに辿りつけない点は省き,$P,Q,X_i,Y_i$ を全て $g$ で割って,$P,Q$ は互いに素な問題に帰着させておく.
格子点 $(x,y)$ を $x+y\ \mathrm{mod}\ 2$ の値によって,つまり,市松模様で塗り分けた時,$P+Q$ が偶数なら同じ色の点にしか行けず,同じ色の点なら行ける.
また,$P+Q$ が奇数なら全ての格子点に移動できることが示すことができる.
時間計算量は $O(\log (\max(P,Q)) + N)$ 程度.

C++によるスパゲッティなソースコード

#include<bits/stdc++.h>
using namespace std;

#define REP(i,a,b) for(i=a;i<b;i++)
#define rep(i,n) REP(i,0,n)

#define mygc(c) (c)=getchar_unlocked()
#define mypc(c) putchar_unlocked(c)

void reader(int *x){int k,m=0;*x=0;for(;;){mygc(k);if(k=='-'){m=1;break;}if('0'<=k&&k<='9'){*x=k-'0';break;}}for(;;){mygc(k);if(k<'0'||k>'9')break;*x=(*x)*10+k-'0';}if(m)(*x)=-(*x);}
template <class T, class S> void reader(T *x, S *y){reader(x);reader(y);}
template <class T, class S, class U> void reader(T *x, S *y, U *z){reader(x);reader(y);reader(z);}

void writer(int x, char c){int s=0,m=0;char f[10];if(x<0)m=1,x=-x;while(x)f[s++]=x%10,x/=10;if(!s)f[s++]=0;if(m)mypc('-');while(s--)mypc(f[s]+'0');mypc(c);}
template<class T> void writerLn(T x){writer(x,'\n');}

template<class T> T GCD(T a,T b){T r; while(a)r=b,b=a,a=r%a; return b;}

int P, Q;
int N, X, Y;

int main(){
  int i, j, k, g, m;
  int res = 0;

  reader(&P,&Q,&N);
  g = GCD(P,Q);
  if(g) P /= g, Q /= g;
  while(N--){
    reader(&X,&Y);
    if(g==0){
      if(X==0 && Y==0) res++;
      continue;
    }
    if(X%g || Y%g) continue;
    X /= g;
    Y /= g;
    if((P+Q)%2==0 && (X+Y)%2!=0) continue;
    res++;
  }
  writerLn(res);

  return 0;
}

Current time: 2017年11月22日00時44分34秒
Last modified: 2015年12月16日00時43分34秒 (by laycrs)
Tags: Competitive_Programming yukicoder
トップページに戻る

Logged in as: unknown user (not login)

ログイン: