기술 블로그

10166번 관중석 본문

알고리즘 문제/BOJ

10166번 관중석

parkit 2020. 1. 8. 08:37
728x90
반응형

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




복습, 문제, 공부




처음에는 어떤 수 x에 대하여 d1 <= 2x <= d2라면,


x는 아예 없애고, 2x - x = x를 세주는 방식으로 했다.


예를 들면, d1 = 3, d2 = 6이라면


3 4 5 6 일 것이고,


3의 정확히 2배인 6이 존재하므로, 3은 세주지 않고, 6 - 3 = 3을 세준다.


즉, 0 4 5 3 → 0 + 4 + 5 + 3 = 12라고 생각했었다.



하지만 이런 문제가 아니었다.


3 4 5 6 에서 6을 봐보자.


6의 공약수들을 보면, 1, 2, 3, 6일 것이다.


이 공약수들은 6하고 위치가 겹칠 것이다.


이러한 것을 활용해야 하는 문제이다.



그리고 중복해서 셈을 해서는 안 되므로

(예시 : i = 8, j = 4이고, i = 4, j = 2일 때, 겹침에도 불구하고 그대로 또 셀 수도 있다.)


2차원 배열로 방문 처리를 한다.


이 때, 최대공약수를 분모로 하여, i와 j를 각각 나누어 준다.


그러면 해당 i에 대하여 i까지 방문 처리를 하게 되고,


i보다 더 큰 숫자 k에 대하여, k는 i까지 방문 처리를 했으니, 세지 않아도 된다.



(사실 조금 헷갈림)




1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include <bits/stdc++.h>
 
using namespace std;
 
#define Max 2002
 
int d1, d2, ans;
bool use[Max][Max];
 
int gcd(int a, int b)
{
    if (b == 0return a;
    return gcd(b, a%b);
}
 
int main()
{
    cin.tie(0);
 
    scanf("%d %d"&d1, &d2);
    
    for (int i = d1; i <= d2; i++) {
        for (int j = 1; j <= i; j++) {
 
            // 최대 공약수
            int m = gcd(i, j);
 
            if (!use[i / m][j / m]) {
                use[i / m][j / m] = true;
                ++ans;
            }
        }
    }
 
    printf("%d\n", ans);
 
    return 0;
}
cs










728x90
반응형

'알고리즘 문제 > BOJ' 카테고리의 다른 글

2212번 센서  (0) 2020.01.09
10165번 버스 노선  (0) 2020.01.08
10164번 격자상의 경로  (0) 2020.01.07
16637번 괄호 추가하기  (0) 2020.01.06
괄호 추가하기 시리즈  (0) 2020.01.06