일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- dreamhack reversing
- 안드로이드 adb start-server
- 제주코딩베이스캠프
- 티스토리챌린지
- 리버싱핵심원리
- 자바스크립트
- 자바스크립트강의 후기
- 안드로이드 모바일 앱 모의해킹
- 자바스크립트 강의 추천
- 리버싱
- 리버싱 입문
- 리버싱 초보
- 리버싱 스터디
- rev-basic 풀이
- 리버싱 플래그
- 리버싱 핵심 원리
- 자바스크립트 강의
- 더오름
- 인프런 강의 추천
- 제주ICT
- adb
- 안드로이드 리버싱
- adb 옵션
- 위니브
- 안드로이드 adb
- 드림핵 플래그
- 강의 체험단 1기
- 오블완
- 드림핵 리버싱
- 드림핵 리버싱 풀이
- Today
- Total
해보자고
[C언어]백준(BOJ) 17427 - '약수의 합2' 본문
#문제 분석
문제 링크 | https://www.acmicpc.net/problem/17427
두 자연수 A와 B가 있을 때, A = BC를 만족하는 자연수 C를 A의 약수라고 한다. 예를 들어, 2의 약수는 1, 2가 있고, 24의 약수는 1, 2, 3, 4, 6, 8, 12, 24가 있다. 자연수 A의 약수의 합은 A의 모든 약수를 더한 값이고, f(A)로 표현한다. x보다 작거나 같은 모든 자연수 y의 f(y)값을 더한 값은 g(x)로 표현한다.
KEY 1 | f(A) 는 자연수 A에 대한 모든 약수의 합이다.
-> ex. A가 4라면 f(4) 는 1+2+4 = 7
KEY 2 | y는 x보다 작거나 같은 모든 자연수들이다.
-> ex. x가 4라면 y는 1,2,3,4
KEY 3 | g(x)는 f(y)값의 합들이다.
-> ex. x가 4라면 y는 1,2,3,4이고, 1은 약수 1 / 2는 약수 1, 2 / 3은 약수 1, 3 / 4는 약수 1, 2, 4 를 가진다. 이 약수들의 합은 1 + 1 + 2 + 1 + 3 + 1 + 2 + 4 = 15 가 된다.
#기본 개념
크게 이 문제를 풀기 위해 알아둬야 할 기본 개념을 2가지 라고 생각했습니다.
첫 번째는 i가 N의 약수일 때 (N / i) * i는 N이 된다는 것.
두 번째는 i가 N의 약수가 아닐 때 (N/i)는 N보다 작거나 같은 i의 배수 중에서 최대값이 된다는 것.
두 가지 기본 개념에 대해 예시를 들어보겠습니다.
첫 번째 두 번째 다 만족을 하고 결과값도 87이 되는 것을 확인할 수 있었습니다.
#코드
해당 문제는 직관적으로 느껴지는 알고리즘으로 문제를 풀면 시간 초과를 발생시킵니다. 시간 초과와 관련한 시간 복잡도는 다음 글에서 다뤄보도록 하겠습니다.
먼저 저도 직관적으로 알고리즘을 설정하고 문제를 풀어봤었는데요.. 시간 초과 코드는 더보기에 추가해 두겠습니다.
#include<stdio.h>
int main() {
int N = 0; // 입력받는 N
int sum = 0;
int ans = 0;
int current_sum = 0;
scanf("%d", &N);
int number[N];
for(int j = 1; j <= N; j++) {
current_sum = 0;
for(int i = 1; i <= j; i++) {
number[i-1] = i;
if(j % number[i-1] == 0){
current_sum = current_sum + number[i-1];
}
}
sum = current_sum + sum;
}
printf("%d\n", sum);
return 0;
}
기본 개념에서 언급한 숫자들의 규칙성을 코드로 잘 표현하는 것이 중요하겠습니다. N보다 같거나 작은 자연수들을 i라고 했을 때, ans = ans + ( N / i ) * i 는 N보다 같거나 작은 자연수들의 약수들의 합이 됩니다.
#include<stdio.h>
int main() {
int N; // 입력되는 N
long long ans = 0;
scanf("%d", &N);
for(int i = 1; i <= N; i++) {
ans += (N / i) * i;
}
printf("%lld\n", ans);
return 0;
}
'프로그래밍 > C언어' 카테고리의 다른 글
[C언어]백준(BOJ) 2609 - '최대공약수와 최소공배수' (0) | 2024.02.01 |
---|---|
[C언어]백준(BOJ) 1037 - '약수' (0) | 2024.01.25 |
[C언어]백준(BOJ) 4375 - '1' (0) | 2024.01.24 |