https://www.acmicpc.net/step/10
약수, 배수와 소수 단계
약수를 구하면서 주어진 수가 완전수인지 판별하는 문제
www.acmicpc.net
6문제
백준 / 5086번
문제
4 × 3 = 12이다.
이 식을 통해 다음과 같은 사실을 알 수 있다.
3은 12의 약수이고, 12는 3의 배수이다.
4도 12의 약수이고, 12는 4의 배수이다.
두 수가 주어졌을 때, 다음 3가지 중 어떤 관계인지 구하는 프로그램을 작성하시오.
- 첫 번째 숫자가 두 번째 숫자의 약수이다.
- 첫 번째 숫자가 두 번째 숫자의 배수이다.
- 첫 번째 숫자가 두 번째 숫자의 약수와 배수 모두 아니다.
입력
입력은 여러 테스트 케이스로 이루어져 있다. 각 테스트 케이스는 10,000이 넘지않는 두 자연수로 이루어져 있다. 마지막 줄에는 0이 2개 주어진다. 두 수가 같은 경우는 없다.
출력
각 테스트 케이스마다 첫 번째 숫자가 두 번째 숫자의 약수라면 factor를, 배수라면 multiple을, 둘 다 아니라면 neither를 출력한다.
풀이
-Python3
while True :
A,B= map(int, input().split())
#마지막 0 0이 들어오면 끝내기
if A==B==0 :
break
if A > B:
if A%B ==0:
print("multiple")
continue
elif A < B :
if B%A ==0:
print("factor")
continue
#둘다 아닌 경우
print("neither")
0 0이 입력으로 들어오면 끝내는 코드이므로 while True로 계속 입력을 받도록 하고, 반복문 초반에서 if문으로 탈출할 수 있게 둔다.
A가 B보다 클 때 A/B의 나머지가 없다면 A가 B의 배수라고 볼 수 있다.
A가 B보다 작을 때 B/A의 나머지가 없다면 반대로 A가 B의 약수라고 볼 수 있다.
따라서 두 경의 if문을 두고 continue로 새 반복문을 시작하게 한다. (break로 끊으면 반복문 활성화가 안 돼서 오류남)
백준 / 2501번
문제
어떤 자연수 p와 q가 있을 때, 만일 p를 q로 나누었을 때 나머지가 0이면 q는 p의 약수이다.
- 6 ÷ 1 = 6 … 0
- 6 ÷ 2 = 3 … 0
- 6 ÷ 3 = 2 … 0
- 6 ÷ 4 = 1 … 2
- 6 ÷ 5 = 1 … 1
- 6 ÷ 6 = 1 … 0
그래서 6의 약수는 1, 2, 3, 6, 총 네 개이다.
입력
첫째 줄에 N과 K가 빈칸을 사이에 두고 주어진다. N은 1 이상 10,000 이하이다. K는 1 이상 N 이하이다.
출력
첫째 줄에 N의 약수들 중 K번째로 작은 수를 출력한다. 만일 N의 약수의 개수가 K개보다 적어서 K번째 약수가 존재하지 않을 경우에는 0을 출력하시오.
풀이
-Python3
N, K= map(int, input().split())
factor = [] #약수를 저장하는 리스트
#약수를 구해서 리스트에 넣기
for i in range(1, N+1, 1) :
if N % i == 0 :
factor.append(i)
#약수의 수가 K보다 작다면 0출력
if len(factor) < K :
print(0)
#그렇지 않을 경우 K번째 약수 출
else :
print(factor[K-1])
약수들의 리스트를 정의해두고 N의 약수 리스트를 저장해두었다가 K번째 약수를 호출하면 된다.
나름 간단...
배열의 원수 개수를 구할 때 len(배열)을 쓰는 점을 헷갈렸고, 인덱스는 0부터 시작하기 때문에 K-1번째 인덱스를 찾아야 한다는 점을 헷갈렸다.
백준 / 9506번
문제
어떤 숫자 n이 자신을 제외한 모든 약수들의 합과 같으면, 그 수를 완전수라고 한다.
예를 들어 6은 6 = 1 + 2 + 3 으로 완전수이다.
n이 완전수인지 아닌지 판단해주는 프로그램을 작성하라.
입력
입력은 테스트 케이스마다 한 줄 간격으로 n이 주어진다. (2 < n < 100,000)
입력의 마지막엔 -1이 주어진다.
출력
테스트케이스 마다 한줄에 하나씩 출력해야 한다.
n이 완전수라면, n을 n이 아닌 약수들의 합으로 나타내어 출력한다(예제 출력 참고).
이때, 약수들은 오름차순으로 나열해야 한다.
n이 완전수가 아니라면 n is NOT perfect. 를 출력한다.
풀이
-Python3
while True :
#리스트 초기화 및 입력 받기
factor = []
n = int(input())
#-1이 들어오면 멈추기
if n == -1 :
break
#약수가 n을 포함하지 않도록 약수 리스트를 만든다.
for i in range(1, n, 1) :
if n % i == 0 :
factor.append(i)
#완전수 판별
if sum(factor) == n :
print(n, "=", " + ".join(map(str, factor)))
else :
print(n, "is NOT perfect.")
약수 리스트를 만들고 sum(factor)로 약수의 합이 n과 같은지 판별을 해주면 된다.
그건 별로 어렵지 않았는데 약수 리스트를 꺼내와서 출력하는 게 헷갈렸다.
print(n, "=", " + ".join(map(str, factor)))
- map(str, factor) : factor의 요소들을 string 형태로 문자열의 합치는 수식이다.
- " + ".join(리스트) : 각 원소들을 " + " 문자로 결합하여 출력 문자열을 생성하는 수식이다.
백준 / 1978번
문제
주어진 수 N개 중에서 소수가 몇 개인지 찾아서 출력하는 프로그램을 작성하시오.
입력
첫 줄에 수의 개수 N이 주어진다. N은 100이하이다. 다음으로 N개의 수가 주어지는데 수는 1,000 이하의 자연수이다.
출력
주어진 수들 중 소수의 개수를 출력한다.
풀이
-Python3
N = int(input())
#파이썬에서는 입력을 리스트로 한번에 넣을 수도 있음
numbers = map(int, input().split())
count = 0
#리스트의 개수 N만큼 소수 판별을 반복한다.
for number in numbers :
#입력이 1일 경우 나눗셈 오류를 방지하기 위해 예외 처리
if number == 1 :
continue
#소수 판별
is_prime = True
for j in range(2, number, 1) :
if number % j == 0 :
is_prime = False
continue
if is_prime:
count += 1
#소수개의 개수 출력
print(count)
원래 소수 판별용 변수를 따로 안 뒀었는데 계산이 제대로 안 돼서 추가한 후기...
소수를 판별하는 반복문에서 continue가 되면 맨 처음 for number in numbers 시작으로 가는 게 아니라 소수를 판별하는 반복문을 재시작하게 된다. 그래서 입력이 1이 아닌 모든 경우에 count+=1이 실행되었다. 여기서 is_prime을 기본 True로 두고, 소수가 아닌 if문에 걸리면 false로 바꾼다. 이후 반복계산문이 종료되고 is_prime 값에 따라서 count를 더하는 방식으로 수정해주었다.
*list로 입력을 한번에 넣을 수 있는 것...
*for i in 배열 으로 배열의 원소를 순차적으로 호출할 수 있는 것...
백준 / 2581번
문제
자연수 M과 N이 주어질 때 M이상 N이하의 자연수 중 소수인 것을 모두 골라 이들 소수의 합과 최솟값을 찾는 프로그램을 작성하시오.
예를 들어 M=60, N=100인 경우 60이상 100이하의 자연수 중 소수는 61, 67, 71, 73, 79, 83, 89, 97 총 8개가 있으므로, 이들 소수의 합은 620이고, 최솟값은 61이 된다.
입력
입력의 첫째 줄에 M이, 둘째 줄에 N이 주어진다.
M과 N은 10,000이하의 자연수이며, M은 N보다 작거나 같다.
출력
M이상 N이하의 자연수 중 소수인 것을 모두 찾아 첫째 줄에 그 합을, 둘째 줄에 그 중 최솟값을 출력한다.
단, M이상 N이하의 자연수 중 소수가 없을 경우는 첫째 줄에 -1을 출력한다.
풀이
-Python3
M = int(input())
N = int(input())
#소수를 추가할 배열 primes
primes = []
#M이상 N이하의 자연수의 소수 판별 반복
for number in range(M, N+1) :
#입력이 1일 경우 나눗셈 오류를 방지하기 위해 예외 처리
if number == 1 :
continue
is_prime = True
for j in range(2, number, 1) :
if number % j == 0 :
is_prime = False
break
if is_prime :
primes.append(number)
#소수의 합 / 소수의 최솟값 출력
if len(primes) == 0 :
print(-1)
else :
print(sum(primes))
print(min(primes))
앞 문제에서 조금만 손보면 된다.
M과 N사이를 반복문으로 돌면서 소수를 만족하는 수만 primes 리스트에 추가한다.
소수가 없을시에는 -1을 출력하고, 있다면 리스트의 합과 최솟값을 출력하면 된다.
백준 / 11653번 (⭐)
문제
정수 N이 주어졌을 때, 소인수분해하는 프로그램을 작성하시오.
입력
첫째 줄에 정수 N (1 ≤ N ≤ 10,000,000)이 주어진다.
출력
N의 소인수분해 결과를 한 줄에 하나씩 오름차순으로 출력한다. N이 1인 경우 아무것도 출력하지 않는다.
풀이
-Python3
import sys
N = int(input())
#N이 1일 경우 아무것도 출력하지 않음
if N == 1 :
sys.exit()
#소인수분해
for i in range(2, N+1) :
while N % i == 0 :
N = N // i
print(i)
if N == 1 :
break
오히려 반복문 때문에 이게 제일 헷갈린듯한.. ?
while N % 1 == 0 -> N이 i로 나누어 떨어질 때까지만 반복하라는 뜻
'기타 > 백준' 카테고리의 다른 글
11. 시간 복잡도 (2) | 2023.11.24 |
---|---|
10. 기하: 직사각형과 삼각형 (0) | 2023.11.18 |
8. 일반 수학 1단계 (2) (0) | 2023.10.09 |
8. 일반 수학 1 (1) (0) | 2023.08.29 |
7. 2차원 배열(2) (0) | 2023.08.07 |