백준 2725번 보이는 점의 개수
< 백준 2725번 보이는 점의 개수 - 마포 코딩박 >
사용한 알고리즘: DP
N이 주어졌을때 NxN 그래프 위의 점 중 원점에서 보이는 점의 개수를 구하는 문제였습니다.
문제풀이는 다음과 같습니다.
(1) (코드 6~7)
'dp[i]: ixi 크기의 정사각 좌표들 중 원점에서 보이는 점의 총 개수' 로 설정합니다.
dp[i] = dp[i-1] + (추가로 보이는 수) 입니다.
(2) (코드 14~33)
dp[1]~dp[1000] 을 구하는 함수를 만듭니다.
(i-1)x(i-1) -> ixi 로 확장될 때 새로 생기는 선분은 정사각형의 윗변과 오른쪽변입니다.
(추가로 보이는 수) = 2*(새로생기는 윗변에 추가로 보이는 수) = 2*((i,1)~(i,i) 중 추가로 보이는 수) 입니다.
점 (x,y)가 보이는지 여부는 기울기로 판별합니다.
(x,y) 가 보이는 점일 때 기울기 y/x 를 bool 배열로 기억하고, 이후는 보이지 않는다 생각합니다.
사용한 알고리즘: DP
N이 주어졌을때 NxN 그래프 위의 점 중 원점에서 보이는 점의 개수를 구하는 문제였습니다.
문제풀이는 다음과 같습니다.
(1) (코드 6~7)
'dp[i]: ixi 크기의 정사각 좌표들 중 원점에서 보이는 점의 총 개수' 로 설정합니다.
dp[i] = dp[i-1] + (추가로 보이는 수) 입니다.
(2) (코드 14~33)
dp[1]~dp[1000] 을 구하는 함수를 만듭니다.
(i-1)x(i-1) -> ixi 로 확장될 때 새로 생기는 선분은 정사각형의 윗변과 오른쪽변입니다.
(추가로 보이는 수) = 2*(새로생기는 윗변에 추가로 보이는 수) = 2*((i,1)~(i,i) 중 추가로 보이는 수) 입니다.
점 (x,y)가 보이는지 여부는 기울기로 판별합니다.
(x,y) 가 보이는 점일 때 기울기 y/x 를 bool 배열로 기억하고, 이후는 보이지 않는다 생각합니다.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <bits/stdc++.h> | |
using namespace std; | |
const int MAX = 1000; | |
int C, N; | |
// dp[x] = x번째 보이는 점들의 총 개수 | |
int dp[MAX+1]; | |
bool visited[MAX+1][MAX+1]; | |
int GCD(int x, int y){ | |
if(y==0) return x; | |
return GCD(y,x%y); | |
} | |
// 기울기로 보이는 점 판별 | |
void MakeDP(int curr){ | |
if(curr>MAX) return; | |
// 추가로 보이는 수 구하기 | |
int ADD = 0; | |
// 반쪽만 구해서 2배 합니다. | |
for(int i=1; i<curr; ++i){ | |
int x = i; | |
int y = curr; | |
// y/x = (y/g)/(x/g) 기약분수 만들기 | |
int g = GCD(y,x); | |
x /= g; | |
y /= g; | |
if(visited[y][x]) continue; | |
ADD++; | |
visited[y][x] = true; | |
} | |
// curr번째 총 개수 = curr-1번째 총 개수 + 추가로 보이는 수 | |
dp[curr] = dp[curr-1]+2*ADD; | |
MakeDP(curr+1); | |
} | |
int main(){ios_base::sync_with_stdio(false); cout.tie(NULL); cin.tie(NULL); | |
cin>>C; | |
dp[1] = 3; | |
visited[1][1] = true; | |
MakeDP(2); | |
while(C--){ | |
cin >> N; | |
cout << dp[N] << '\n'; | |
} | |
return 0; | |
} |
댓글
댓글 쓰기
긴 글 읽어주셔서 감사합니다.
궁금한게 있으시다면 댓글 달아주세요!