[Java] 백준 2725번 (보이는 점의 개수)

2024. 4. 6. 22:43·BOJ, Programmers

https://www.acmicpc.net/problem/2725

 

2725번: 보이는 점의 개수

첫째 줄에 테스트 케이스의 개수 C(1<=C<=1,000)가 주어진다. 각 테스트 케이스는 자연수 N(1<=N<=1,000) 하나로 이루어져 있고, 한 줄에 하나씩 주어진다.

www.acmicpc.net

 

알고리즘 분류

  • 수학
  • 정수론
  • 누적 합
  • 유클리드 호제법

 

풀이

유클리드 호제법 알고리즘과 다이나믹 프로그래밍을 이용해 풀었다.

0,0 에서 보이는 점의 갯수를 구하는 문제다.

 

예를 들어보자 

x, y 좌표가 (2, 4)인 좌표는 (1, 2)에 가려서 안보인다. 왜냐하면 기울기가 같기 때문이다. 

이 좌표가 가려서 안보이는지, 아니면 (0, 0)에서 보이는지 유클리드 호제법을 사용해 알 수 있는데,

x, y 좌표의 최대 공약수가 1이면 보이고 1이 아니면 안보인다.

아래의 그림을 통해 설명하자면 . 

 

(2, 4)의 좌표의 최대 공약수는 2이다. 따라서 안보인다고 할 수 있다. 

 

최대 공약수를 구한는 gcd 메서드이다.

public static boolean gcd(int x, int y) {
	if(y==0) return x==1;
	return gcd(y, x%y);
} // gcd

두 수가 서로소 ( 서로의 약수가 1밖에 없는 관계 ) 인지 판단하는 gcd 메서드이다.

두 수가 주어졌을 때 x와 y의 최대 공약수는 y와 x 를 y로 나눈 나머지의 최대공약수와 같다는 원리를 이용한다.

이 과정을 y가 0일 때 까지 반복해 y가 0 일때 a가 최대 공약수이다.

따라서 최대공약수가 1이면 x==1가 맞으므로 true를 반환한다. 

 

 

전에 구했던 갯수에서 새롭게 보이는 갯수만 더하면 되므로 dp를 사용해 값을 구했다.

cnt라는 값은 i ( x값 ), j (y값) 의 최대 공약수가 1이면 하나씩 증가하고 아니면 0을 더해 증가하지 않도록 했다

마지막에 2를 곱한 것은 대각선을 기준으로 한 구역만 구하므로 2를 곱했다.

dp[1] = 3;
int cnt;
   for (int i = 2; i < dp.length; i++) {
   cnt = 0;
   for(int j = 1 ; j < i ; j++) {
	  cnt += (gcd(i, j) == true) ? 1: 0;
   }
   dp[i] = dp[i-1] + 2 * cnt;
}

 

 

아래는 전체 정답 코드이다.

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {
	public static void main(String[] args) throws NumberFormatException, IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		int n = Integer.parseInt(br.readLine());
		
		int temp[] = new int[n];
		for (int i = 0; i < temp.length; i++) {
			int a = Integer.parseInt(br.readLine());
			temp[i] = a;
		} // for
		
		int [] dp = new int[1000 + 1]; // 각 케이스는 1000이하
		
		dp[1] = 3;
		int cnt;
		for (int i = 2; i < dp.length; i++) {
			cnt = 0; // 보이는 갯수 구하는 변수
			for(int j = 1 ; j < i ; j++) {
				cnt += (gcd(i, j) == true) ? 1: 0; // true면 1을 더하고 false면 0을 더한다.
			}
			dp[i] = dp[i-1] + 2 * cnt;
		}
		
		StringBuilder sb = new StringBuilder();
		for (int i = 0; i < temp.length; i++) {
			sb.append(dp[ temp[i] ]).append("\n");
		} // for
		
		System.out.println(sb.substring( 0, sb.length()-1 ).toString());
		
	}
	
	public static boolean gcd(int x, int y) {
		if(y==0) return x==1;
		return gcd(y, x%y);
	} // gcd
}

'BOJ, Programmers' 카테고리의 다른 글

[Java] 백준 1543번 (문서 검색) 자바 문제 풀이  (0) 2024.04.08
[Java] 백준 1448 번 (삼각형 만들기)  (0) 2024.04.08
[Java] 백준 1449번 (수리공 항승)  (0) 2024.04.06
[Java] 백준 1577 (도로의 개수)  (2) 2024.04.05
[Java] 백준 1926 (그림) 자바 문제 풀이  (0) 2024.04.05
'BOJ, Programmers' 카테고리의 다른 글
  • [Java] 백준 1543번 (문서 검색) 자바 문제 풀이
  • [Java] 백준 1448 번 (삼각형 만들기)
  • [Java] 백준 1449번 (수리공 항승)
  • [Java] 백준 1577 (도로의 개수)
Economy98
Economy98
공부하고 기록하기
  • Economy98
    Economy_Dev
    Economy98
  • 전체
    오늘
    어제
    • 분류 전체보기 (74)
      • Spring Framework (11)
      • BOJ, Programmers (22)
      • Java (4)
      • JDBC (6)
      • JPA (9)
      • Spring Transaction (3)
      • Algorithm (1)
      • Web (5)
      • Projects (2)
        • 쇼핑몰 프로젝트 (0)
        • 열람실 & 도서관 프로젝트 (2)
      • Network (2)
      • 나의 공부방 (5)
      • 끄적끄적 (1)
      • Error Log (3)
      • CS (0)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
    • Github
  • 링크

    • Github
  • 공지사항

  • 인기 글

  • 태그

    jdbc
    자바 문제
    트랜잭션
    정렬
    자바
    자바 문제 풀이
    스프링
    propagation
    다이나믹 프로그래밍
    백준 자바 풀이
    Spring
    백준
    그리디 알고리즘
    JPA
    브루트포스 알고리즘
    java
    백준 풀이
    restful api
    예외 처리
    스프링부트
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.1
Economy98
[Java] 백준 2725번 (보이는 점의 개수)
상단으로

티스토리툴바