문제

  • 지난주에, 민식주식회사는 IIHF(International Ice Hockey Federation)로부터 긴급한 전화를 받았다.

IIHF는 같은 팀이 링크안에 너무 많으면 알람이 울리는 시스템을 설치해달라고 요청했다. 시스템은 다음과 같이 3개의 부분으로 이루어진다.

  1. 디지털카메라가 링크의 사진을 매 1초마다 찍는다.
  2. 디지털카메라가 찍은 사진에서 각 선수의 위치를 뽑아낸다.
  3. 하키 링크 안에 같은 팀 선수가 총 몇 명인지 계산한다.

하키 링크는 (X, Y)가 가장 왼쪽 아래 모서리인 W * H 크기의 직사각형과, 반지름이 H/2이면서 중심이 (X, Y+R), (X+W, Y+R)에 있는 두 개의 원으로 이루어져 있다. 아래 그림을 참고한다.

선수들의 위치가 주어질 때, 링크 안 또는 경계에 있는 선수가 총 몇 명인지 구하는 프로그램을 작성하시오.

입력

  • 첫째 줄에 수 W H X Y P가 주어진다. P는 선수의 수이다. W와 H는 100보다 작거나 같은 자연수이고, H는 짝수이다. X와 Y는 절댓값이 100보다 작거나 같은 정수이다. P는 최대 100인 자연수이다. 둘째 줄부터 P개의 줄에 각 선수들의 x좌표와 y좌표가 주어진다. 이 좌표는 절댓값이 300보다 작거나 같은 정수이다.

출력

  • 첫째 줄에 링크 안에 있는 선수의 수를 출력한다.

예제

예제 입력
20 10 5 0 3
15 5
1 5
1 1

예제 출력
2

접근

  • 직사각형은 계산하기 쉽다. 사람들이 반원 안에 있는지 확인하려면 어떻게 해야 할까?
  • 각 점들의 좌표만 알면 쉽게 접근 할 수 있을 것 같다.

내가 생각한 풀이

  • 그림 상으로 좌표들의 값을 모두 확인 할 수 있기 때문에 주어진 값을 대입만 시키면 대표적인 지점(직사각형의 왼쪽, 오른쪽 모서리, 원의 왼쪽 오른쪽 중심)등이 다 나온다.
    • 이러한 대표적인 지점을 경계로 삼고 그 안에 들어있는 사람만 세면 된다.
  • 각 점과 원의 중심과의 거리를 계산 한 후 그 값이 반지름보다 작으면 그 사람은 경기장 내부에 있는 것이다!

코드

#include<iostream>
using namespace std;
struct xy{
  int x;
  int y;
};
int main(void){
  int W,H,X,Y,P,r=0;
  struct xy loc[101];
  cin>>W>>H>>X>>Y>>P;
  for(int i = 0 ;i<P;i++) cin>>loc[i].x>>loc[i].y;
  for(int i = 0; i<P;i++){
    int x = loc[i].x, y = loc[i].y;
    if(x<X || y<Y){
      if((X-x)*(X-x) + (Y+H/2-y)*(Y+H/2-y) <= (H*H)/4) r++;
    }
    else if(x>X+W || y>Y+H){
      if((X+W-x)*(X+W-x) + (Y+H/2-y)*(Y+H/2-y) <= (H*H)/4) r++;
    }
    else{
      if(x>=X && x<=X+W && y>=Y && y<=Y+H) r++;
    }
  }
  cout<<r;
  return 0;
}