알고리즘 PS/BruteForce

백준 #1977 완전제곱수

explorer999 2023. 8. 31. 13:27

문제

M과 N이 주어질 때 M이상 N이하의 자연수 중 완전제곱수인 것을 모두 골라 그 합을 구하고 그 중 최솟값을 찾는 프로그램을 작성하시오. 예를 들어 M=60, N=100인 경우 60이상 100이하의 자연수 중 완전제곱수는 64, 81, 100 이렇게 총 3개가 있으므로 그 합은 245가 되고 이 중 최솟값은 64가 된다.

입력

첫째 줄에 M이, 둘째 줄에 N이 주어진다. M과 N은 10000이하의 자연수이며 M은 N보다 같거나 작다.

 

출력

M이상 N이하의 자연수 중 완전제곱수인 것을 모두 찾아 첫째 줄에 그 합을, 둘째 줄에 그 중 최솟값을 출력한다. 단, M이상 N이하의 자연수 중 완전제곱수가 없을 경우는 첫째 줄에 -1을 출력한다.

예제 입력 1 복사

60
100

예제 출력 1 복사

245
64

예제 입력 2 복사

75
80

예제 출력 2 복사

-1

 

내 풀이:

m=int(input())
n=int(input())

arr=[]

for i in range(1,101):
    i*=i
    if i>=m and i<=n:
        arr.append(i)
a=0
       
for i in arr:
    a+=i
   
if len(arr)>=1:
    print(a)
    print(arr[0])  
else: print('-1')

#

m,n을 정수형으로 입력받음. M과 N은 10000이하의 자연수 이므로, 

1부터 100까지의 자연수 i에 대해서 i*i가 m이랑 n사이에 있으면 arr이라는 리스트에 i의제곱수를 넣음.

리스트에 있는 수들의 합과 최솟값 출력

 

#

지금 보니까 이것도 합 구할 떄 sum(map(int,str(i)))이거 썼어도 됐겠다.

 

m=int(input())
n=int(input())
num=[]

i=1
while i**2<=n:
    if m<=i**2:
        num.append(i**2)
    i=i+1
if num==[]:
    print(-1)
else:
    print(sum(num))
    print(num[0])

# 다른 사람 풀이

m,n을 정수형으로 입력 받음.

1로 시작하는 i의 제곱이 b보다 작거나 같은 동안, 그게 a보다 크거나 같으면 num이라는 리스트에 i의 제곱수를 넣음.

( i*i라고 하는 대신 이 사람은 i**2라 표혔했음. 제곱하는 수가 커질 수록 저렇게 하는 게 맞긴 함. )

그리고 if조건을 만족시키든 그렇지 않든, while문 한번 돌 때마다 i에 1씩 더함. 

만약 while문이 끝났는데 num이라는 리스트에 원소가 하나도 없으면 -1을 출력, 그게 아니라면 합과 최솟값을 출력.

 

#

이렇게 하면 시간이 좀 덜 걸리는 이유가 뭘까?

1부터 101까지 다 안 보고 m보다 큰 수 나오면 while문이 끝나서?

그럼 나처럼 굳이 for문을 써야겠다면 range를 1,n 이렇게 했으면 훨씬 간단할 뻔했다. (if문 조건도 간단해지니까)

sum함수도 이제 쓸 수 있으면 써야겠다.

 

m = int(input())
n = int(input())
 
num = []
for i in range(m, n+1):
    root = int(i ** 0.5)
    if i == root ** 2:num.append(i)
 
if num == []:
    print(-1)
else:
    print(f'{sum(num)}\n{min(num)}')

#

이건 제곱수를 구한 게 아니라 m과 n의 제곱근을 구하는 방식. 음... 문제 조건에 입력값 범위가 명시되어있지 않았다면 이렇게 해야할 것 같다.

m과 n 사이의 수에 대하여 i의 제곱근은 root

i가 root의 제곱과 같다면 num리스트에 append해라? 이게 이해가 안됐는데 이제 알았다.

출력은 뭐 다 비슷하게 했다.