안 쓰던 블로그

알고리즘-수학2 본문

알고리즘/Algorithm

알고리즘-수학2

proqk 2019. 7. 6. 13:53
반응형

수학

수학2에서는 수학1에서 다뤘던 내용을 기반으로 조금 더 응용하는 문제를 다뤄보겠습니다. 수학1 게시글(https://foxtrotin.tistory.com/95)을 보고 오면 도움이 되실 겁니다.

 

 

1. 나머지 연산

나머지 연산을 쓰는 유형에는 몇 가지가 있습니다. 나머지의 값이 필요할 때, 특정 수의 배수인지 판별, 짝수인지 홀수인지 판별, 몇 개의 수를 계속 돌리고 싶을 때, 너무 큰 수가 정답일 때 나머지 연산 후 정답을 출력할 때 등등.. 여기서는 몇 개의 수를 계속 돌리고 싶은 경우 어떻게 해야 하는지 알아보겠습니다.

 

#include <stdio.h>
int main(){
    int a[3] = { 1,2,3 };
 
    for (int i = 0; i < 6; i++) {
        printf("%d ", a[i % 3]);
    }
}

 

맨 처음 돌 때 i = 0입니다. a[0]을 출력합니다.

두 번째 돌 때는 i = 1입니다. a[1]을 출력합니다.

세 번째 돌 때는 i = 2입니다. a[2]을 출력합니다.

그러면 네 번째 돌 때는? i = 3이고 3%3 = 0이니까 a[0]을 다시 출력합니다.

 

이런 식으로 나머지 연산을 이용하면 특정 수들을 계속 반복해서 사용할 수 있습니다.

 

 

2. 소수

어떤 수가 소수인지 알 수 있는 간단한 방법으로는 2부터 그 수 이전까지의 모든 수를 하나씩 나머지 연산을 해보면서 나누어 떨어지는지 검사하는 것입니다. 그런데 이 방법을 엄청 큰 수에도 사용할 수 있을까요? 아니면 어떤 수 이하의 모든 소수를 출력하라는 문제에서도 하나씩 검사해야 할까요? 더 효율적인 방법이 필요합니다.

 

생각해봅시다. 6 2 3의 배수입니다. 2 3은 소수입니다. 15 3 5의 배수입니다. 3 5는 소수입니다. 21 3 7의 배수입니다. 3 7도 소수입니다.

규칙이 보이나요? 어떤 수가 소수인지 알기 위해서는 굳이 전부 돌리지 않아도 됩니다. 어떤 수보다 작은 수의 소수들로만 나누어보면 되는 것입니다.

 

다른 방법을 생각해봅시다. 어떤 수까지의 모든 소수를 구하고 싶습니다. 어떤 수보다 작은 수를 전부 배열에 넣고 소수가 아닌 수를 지워버리면 소수만 남습니다. 2를 제외한 모든 2의 배수를 지우고, 3을 제외한 모든 3의 배수를 지우고, 4는 이미 지워졌으니까 패스, 5를 제외한 모든 5의 배수를 지우고..를 반복합니다. 이것은 에라토스테네스의 체라는 알고리즘입니다.

 

 

구현 자체는 어렵지 않습니다. 코드를 보지 않고 직접 해보시는 것을 추천합니다.

int a[10000001];
long long solution(int N) {
    long long answer = 0;
    for (int i = 2; i <= N; i++) {
        a[i] = i;
    }
    for (int i = 2; i <= sqrt(N); i++) {
        if (a[i]) {
            for (int j = i * 2; j <= N; j += i) {
                a[j] = 0;
            }
        }
    }
    for (int i = 2; i <= N; i++) {
        if (a[i] != 0) answer += a[i];
    }
    return answer;
}

 

 

3. 팩토리얼

고등학교에서 배꿨던 팩토리얼을 이제는 컴퓨터한테 계산을 시켜봅시다. 6! 이후의 팩토리얼 수부터 시작하겠습니다. 6! 720, 7! 5040, 8! 40320, 9! 362880, 10! 368800… 25! 1551121004*10^25, 50! 3041409320*10^64. 뭔가 반복되는 점이 보입니다. 계산을 할수록 뒤에 0이 계속 늘어나고 있습니다. 0 10을 얼마나 곱하느냐에 따라 결정됩니다. , 팩토리얼 뒤에 붙는 0의 개수는 팩토리얼을 이루는 수의 소인수 중, 2 5의 개수에 따라 결정됩니다.

 

정리를 해보겠습니다.

10! = 1*2*3…*10

10! = 1*2*3*(2*2)*5*(2*3)…*(2*5)

10! = 2^8 * 3^4 * 5^2 * 7

10! = (2^2 * 5^2) * 2^6 * 3^4 * 7

10! = 10^2 * 2^6 * 3^4 * 7

 

따라서 2 5의 개수 중 작은 값이 0의 개수(=10의 개수)가 됩니다. 여기서는 두 개네요.

 

 

추천 문제

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

 

2991번: 사나운 개

문제 창영 마을의 우체부, 우유배달원, 신문배달원은 상근이네 집에 가는 것을 매우 싫어한다. 그 이유는 상근이네 집에는 사나운 개 두 마리가 지키고 있기 때문이다. 하지만, 그들은 이 개의 행동이 예측 가능하다는 것을 모르고 있다. 매일 아침, 개 한마리는 A분동안 공격적이고, B분동안 조용히 쉬고 있다. 또다른 개는 C분동안 공격적이고, D분동안 조용히 쉰다. 두 개는 이 행동을 계속해서 연속적으로 반복한다. 우체부, 신문배달원, 우유배달원의 도착 시간

www.acmicpc.net

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

 

2960번: 에라토스테네스의 체

문제 에라토스테네스의 체는 N보다 작거나 같은 모든 소수를 찾는 유명한 알고리즘이다. 이 알고리즘은 다음과 같다. 2부터 N까지 모든 정수를 적는다. 아직 지우지 않은 수 중 가장 작은 수를 찾는다. 이것을 P라고 하고, 이 수는 소수이다. P를 지우고, 아직 지우지 않은 P의 배수를 크기 순서대로 지운다. 아직 모든 수를 지우지 않았다면, 다시 2번 단계로 간다. N, K가 주어졌을 때, K번째 지우는 수를 구하는 프로그램을 작성하시오. 입력 첫째 줄에

www.acmicpc.net

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

 

4948번: 베르트랑 공준

문제 베르트랑 공준은 임의의 자연수 n에 대하여, n보다 크고, 2n보다 작거나 같은 소수는 적어도 하나 존재한다는 내용을 담고 있다. 이 명제는 조제프 베르트랑이 1845년에 추측했고, 파프누티 체비쇼프가 1850년에 증명했다. 예를 들어, 10보다 크고, 20보다 작거나 같은 소수는 4개가 있다. (11, 13, 17, 19) 또, 14보다 크고, 28보다 작거나 같은 소수는 3개가 있다. (17,19, 23) n이 주어졌을 때, n보다 크고, 2n보

www.acmicpc.net

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

 

1676번: 팩토리얼 0의 개수

N!에서 뒤에서부터 처음 0이 아닌 숫자가 나올 때까지 0의 개수를 구하는 프로그램을 작성하시오.

www.acmicpc.net

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

 

2553번: 마지막 팩토리얼 수

첫째 줄에 N이 주어진다. N은 20,000보다 작거나 같은 자연수 이다.

www.acmicpc.net

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

 

7489번: 팩토리얼

문제 n!은 정수 n에 대한 팩토리얼 수를 나타내는데, 이는 1부터 n까지의 모든 정수의 곱을 의미한다. 팩토리얼은 굉장히 빨리 커지기 때문에 13!는 대부분의 컴퓨터에서 32비트 정수형을, 70!은 대부분의 부동 소수점 변수의 범위를 넘어선다. 우리는 n!에 대하여 0이 아닌 최우측 수(the rightmost non-zero digit)를 찾으려고 한다. 예를 들어, 5! = 1 * 2 * 3 * 4 * 5 = 120 이므로 5!의 최우측 0이 아닌

www.acmicpc.net

 

반응형

'알고리즘 > Algorithm' 카테고리의 다른 글

단순구현  (0) 2019.07.06
음수를 나머지 연산하려면 어떻게 해야 할까?  (2) 2019.07.06
알고리즘-수학1  (0) 2019.07.06
std::sort 정렬 기준 바꾸기  (1) 2019.05.12
C언어 1차원, 2차원 배열  (0) 2019.05.09
Comments