티스토리 뷰
https://www.acmicpc.net/problem/2108
2108번: 통계학
첫째 줄에 수의 개수 N(1 ≤ N ≤ 500,000)이 주어진다. 단, N은 홀수이다. 그 다음 N개의 줄에는 정수들이 주어진다. 입력되는 정수의 절댓값은 4,000을 넘지 않는다.
www.acmicpc.net
이번 문제는 생각보다 쉽지 않았음 .. 5분컷일 줄 알았는데 오래걸림 ^^ ,,,
그래도 파이썬 공부하려고 잘 못 쓰는 딕셔너리, 메소드 등등을 써보려고 노력해서 알아낸 사실이 꽤 있다.
그리고 Python3는 자꾸 타임리밋 떠서 ㅠㅠ 그냥 pypy3으로 돌려버림 ,,
Python3에서 돌아가는 방법 아래에!!!
우선 내 풀이
첫번째 코드
import sys
n = int(sys.stdin.readline())
arr = []
idx = {}
#숫자 받아서 arr 리스트에 넣기
for i in range(n):
num = int(sys.stdin.readline())
arr.append(num)
#idx에 입력받은 숫자가 키로 없으면 해당 숫자를 키로하여 값을 1로 세팅
if num not in idx:
idx[num] = 1
#입력받은 숫자가 idx에 키로 있으면, 하나가 더 들어온 것이므로 값을 1 더해줌
elif num in idx:
idx[num]+=1
#갯수 1개일 때를 따로 빼기
if n==1:
print(arr[0])
print(arr[0])
print(arr[0])
print(0)
#갯수가 1개 이상이면
else:
#우선 오름차순 정렬
arr.sort()
#산술평균
avg = int(round(sum(arr)/n))
print(avg)
#중앙값은 오름차순 정렬한 것에서 가운데 값
mid = arr[int(n/2)]
print(mid)
#최빈값
#sorted 하면 리스트 반환. 원소는 튜플
#빈도수 내림차순(큰->작은), 키값 오름차순(작은->큰)
idx = sorted(idx.items(),key = lambda x:(-x[1],x[0]))
#만일 최빈값이 두개라면, 1번째 인덱스의 값, 즉 idx[1][0] 출력하기
#최빈값이 한개라면 0번째 인덱스의 값, 즉 idx[0][0] 출력하기
for i in range(1,len(idx)):
if idx[0][1] == idx[i][1]:
print(idx[1][0])
break;
else:
print(idx[0][0])
break;
ran = arr[n-1] - arr[0]
print(ran)
첫번째 풀이에서 최빈값이 여러개인지 체크할 때, 굳이 for문을 쓴 것 같아서 그냥 첫번째와 두번째 값만 남겼다.
(어차피 최빈값 순으로 정렬했고, 그 다음은 값에 대해 오름차순 했으므로)
이게 시간 더 적게 걸릴 줄 알았는데 오히려 더 걸림.. 왜지..
아무튼 두번째 풀이
두번째 코드
import sys
n = int(sys.stdin.readline())
arr = []
idx = {}
#숫자 받아서 arr 리스트에 넣기
for i in range(n):
num = int(sys.stdin.readline())
arr.append(num)
#idx에 입력받은 숫자가 키로 없으면 해당 숫자를 키로하여 값을 1로 세팅
if num not in idx:
idx[num] = 1
#입력받은 숫자가 idx에 키로 있으면, 하나가 더 들어온 것이므로 값을 1 더해줌
elif num in idx:
idx[num]+=1
#갯수 1개일 때를 따로 빼기
if n==1:
print(arr[0])
print(arr[0])
print(arr[0])
print(0)
#갯수가 1개 이상이면
else:
#우선 오름차순 정렬
arr.sort()
#산술평균
avg = int(round(sum(arr)/n))
print(avg)
#중앙값은 오름차순 정렬한 것에서 가운데 값
mid = arr[int(n/2)]
print(mid)
#최빈값
#sorted 하면 리스트 반환. 원소는 튜플
#빈도수 내림차순(큰->작은), 키값 오름차순(작은->큰)
idx = sorted(idx.items(),key = lambda x:(-x[1],x[0]))
#idx의 첫번째, 두번째 값만 남겨두기
#만일 최빈값이 두개라면, 1번째 인덱스의 값, 즉 idx[1][0] 출력하기
#최빈값이 한개라면 0번째 인덱스의 값, 즉 idx[0][0] 출력하기
idx =[idx[0],idx[1]]
if idx[0][1] == idx[1][1]:
print(idx[1][0])
else:
print(idx[0][0])
#범위
ran = arr[n-1] - arr[0]
print(ran)
다른 사람 코드 1
import sys
import math
N = int(sys.stdin.readline())
counter = 8001 * [0]
for i in range(N):
counter[int(sys.stdin.readline()) + 4000] += 1
average = 0
for i, value in enumerate(counter):
if value != 0:
average += (i - 4000) * value
average = average / N
if average - math.floor(average) < 0.5:
average = math.floor(average)
else:
average = math.floor(average) + 1
temp = 0
for i in range(len(counter)):
if temp < (N//2 + 1):
if counter[i] != 0:
temp += counter[i]
med = i - 4000
continue
break
if N == 1:
med = counter.index(max(counter)) - 4000
if counter.count(max(counter)) == 1:
freq = counter.index(max(counter)) - 4000
else:
res_counter = [i for i, value in enumerate(counter) if value == max(counter)]
freq = res_counter[1] - 4000
idx = [i for i, value in enumerate(counter) if value != 0]
rang = max(idx) - min(idx)
sys.stdout.write(str(average) + '\n' + str(med) + '\n' + str(freq) + '\n' + str(rang))
1등 코든데 지금은 이해할 뇌 용량이 안됨 ,,ㅋ ㅋ 나중에 봐야지 ..
다른 사람 코드 2
import sys
# import math
N = int(sys.stdin.readline().strip())
arr = [int(sys.stdin.readline().strip()) for _ in range(N)]
arr = sorted(arr)
#빈도수 배열
cnt_arr = {}
sum_arr = 0
for i in arr:
sum_arr += i
if i in cnt_arr:
cnt_arr[i] += 1
else:
cnt_arr[i] = 1
avr = round(sum_arr / len(arr))
mid = arr[N//2]
rng = max(arr) - min(arr)
#빈도수 배열의 빈도들 중 최대값 구하기
max_cnt = max(cnt_arr.values())
tmp = []
#최빈값들의 key(최빈값에 해당하는 입력받은 숫자)를 tmp에 담기
for i in cnt_arr:
if max_cnt == cnt_arr[i]:
tmp.append(i)
#최빈값 배열을 입력받은 숫자에 대해 오름차순 정렬
tmp = sorted(tmp)
# 최빈값이 1개이상이면, 두번째 값 출력
if len(tmp) > 1:
mode = tmp[1]
#최빈값이 1개이면 해당값 출력
else:
mode = tmp[0]
print(avr)
print(mid)
print(mode)
print(rng)
오,, 이분 코드 나랑 비슷한데 더 간단해서 좋다 ..
나는 처음부터 빈도수 리스트를 빈도수 내림차순, 입력받은 수 오름차순으로 정렬했는데 이분은 그냥 최빈값을 max()로 구하고, 최빈값에 대해서만 오름차순 정렬해서 뽑아냄 ..
게다가 이분꺼는 Python3 돌아감
그러면 내꺼도 Python3에서 돌아가게 수정해보자 ..
지금 ..
악 input()을 sys.stdin.readline()으로 바꾸니까 Python3 통과함 ㅠㅠㅠㅠ 심지어 다름사람코드2 보다 메모리 적게쓰고 시간도 적게 소요된다 .. 머선 일이지 ..
암튼 이제 이거 써야겠다 ..
꺠달은 점
1) 딕셔너리 공부하기
https://dojang.io/mod/page/view.php?id=2309
파이썬 코딩 도장: 25.3 딕셔너리 표현식 사용하기
리스트와 마찬가지로 딕셔너리도 for 반복문과 if 조건문을 사용하여 딕셔너리를 생성할 수 있습니다. 다음과 같이 딕셔너리 안에 키와 값, for 반복문을 지정하면 됩니다. {키: 값 for 키, 값 in 딕
dojang.io
2) sys.stdin.readline() 쓰기
3) arr[1:][1] 은 arr리스트의 1번째에서 마지막까지의 원소들 중 첫번째, 즉 arr[1]임.
4) 내림차순 정렬하고 싶을 때 reverse = True 해도 되지만, 정렬 기준이 두가지 이상이고 어떤 것에 대해서는 오름차순, 다른 것에 대해서는 내림차순 정렬하고 싶을 떄 내림차순 하고 싶은 기준에 '-'를 붙여주면 내림차순 정렬됨.
'알고리즘 > Baekjoon' 카테고리의 다른 글
[CodingTest] python 백준 Baekjoon #2751 수 정렬하기 2 / 정렬 / stdout() (0) | 2021.11.20 |
---|---|
[CodingTest] python 백준 Baekjoon #1152 단어의 개수 / 문자열 / strip() (0) | 2021.11.20 |
[CodingTest] python 백준 Baekjoon #10814 나이순 정렬 / 정렬 (0) | 2021.11.19 |
[CodingTest] python 백준 Baekjoon #1181 단어 정렬 / 정렬 (0) | 2021.11.19 |
[CodingTest] 백준 Baekjoon #1427 소트인사이드 / 정렬 (0) | 2021.11.19 |
- Total
- Today
- Yesterday
- 덱
- 정렬
- baekjoon
- bootstrap
- html
- 프로그래머스
- 단계별로풀어보기
- 고득점 키트
- web
- R
- 브루트 포스
- 자바
- javascript
- append
- 스프링
- 자바스크립트
- jsp
- CSS
- jQuery
- 장고
- Case When
- Java
- 파이썬
- Oracle
- python
- 문자열
- 백준
- Django
- 큐
- brute force
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |