Skip to content

Conversation

@hadongun
Copy link
Collaborator

@hadongun hadongun commented May 7, 2025

πŸ”— 문제 링크

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

βœ”οΈ μ†Œμš”λœ μ‹œκ°„

2.5h

✨ μˆ˜λ„ μ½”λ“œ

λ¬Έμ œμ—μ„œ μ œμ‹œν•œ 쑰건 쀑 μ΅œλΉˆκ°’μ„ κ΅¬ν•˜λŠ” λ¬Έμ œμ—μ„œ λ°œμƒμ— 였랜 μ‹œκ°„μ΄ κ±Έλ Έμ–΄μš”...
μž…λ ₯ λ°›λŠ” μ •μˆ˜μ˜ λ²”μœ„κ°€ -4000<n<4000 으둜 μŒμˆ˜λ„ ν¬ν•¨λ˜μ–΄ μžˆμ–΄μ„œ μ²˜μŒμ— κ΅¬ν˜„ν•  λ•Œ 인덱슀λ₯Ό μ΄μš©ν•΄μ„œ κ΅¬ν•˜λ € ν–ˆλŠ”λ°, μΈλ±μŠ€λŠ” μŒμˆ˜κ°€ μ•ˆ λ“€μ–΄κ°€ 음수.. μ–‘μˆ˜ λ‚˜λˆ μ„œ λ„μ „ν•˜λ €λ‹€ μ‹€νŒ¨ν•˜μ˜€μŠ΅λ‹ˆλ‹€.-> μ§€ν”Όν‹°μ—κ²Œ 아이디어λ₯Ό μ–»μ–΄λ΄€μŠ΅λ‹ˆλ‹€..!

처음 수λ₯Ό μž…λ ₯받은 ν›„ sort()λ₯Ό μ‚¬μš©ν•΄ μ˜€λ¦„μ°¨μˆœ μ •λ ¬ ν•˜μ˜€μŠ΅λ‹ˆλ‹€.

μ‚°μˆ ν‰κ· μ€ 각 수λ₯Ό for문으둜 각각 더해 리슀트의 크기둜 λ‚˜λˆ„μ–΄ μ£Όμ—ˆμŠ΅λ‹ˆλ‹€!.

전체 수의 κ°œμˆ˜κ°€ ν™€μˆ˜λΌκ³  λ¬Έμ œμ— μ£Όμ–΄μ‘ŒκΈ° λ•Œλ¬Έμ— 전체 크기λ₯Ό μ •μˆ˜ μ—°μ‚°μž //둜 λ‚˜λˆˆ 값이 쀑앙값이 λ©λ‹ˆλ‹€(μ†Œμˆ˜μ  μ΄ν•˜λŠ” 버리기 λ•Œλ¬Έ)

κ°€μž₯ λ¬Έμ œμ˜€λ˜ μ΅œλΉˆκ°’μΈλ°, μš°μ„  μž…λ ₯ 받은 수λ₯Ό 인덱슀둜 κ·ΈλŒ€λ‘œ μ΄μš©ν•˜κΈ°λ‘œ ν•˜μ˜€μŠ΅λ‹ˆλ‹€. λ‹€λ§Œ μ •μˆ˜μ˜ λ²”μœ„κ°€ -40004000μ΄λ―€λ‘œ
μž…λ ₯ 받은 수 + 4000을 인덱슀 κ°’μœΌλ‘œ ν•˜μ—¬ 0
8000인 count리슀트λ₯Ό μƒμ„±ν•˜μ˜€μŠ΅λ‹ˆλ‹€.
ex) 5λ₯Ό μž…λ ₯ λ°›μœΌλ©΄ count[5]의 값이 1 μ¦κ°€ν•˜λŠ” μ‹μœΌλ‘œ 카운트 ν•˜μ˜€μŠ΅λ‹ˆλ‹€.

쀑간에 Max = count[0]μ΄λž‘ temp = 0은 이전에 μ‹œλ„ν•  λ•Œ μ“°λ˜ μ½”λ“œλΌ ν•„μš” μ—†λŠ” μ½”λ“œμΈλ° κΉœλΉ‘ν•˜κ³  λͺ» μ§€μ› λ„€μš”.. λ¬΄μ‹œν•΄μ£Όμ„Έμš”

이후 maxν•¨μˆ˜λ₯Ό μ‚¬μš©ν•΄ κ°€μž₯ 많이 λ“±μž₯ν•œ 횟수λ₯Ό κ΅¬ν•˜μ˜€μŠ΅λ‹ˆλ‹€.
이후 if문으둜 Max κ°’κ³Ό count의 값이 κ°™λ‹€λ©΄ κ·Έ 값을 max_list에 μ €μž₯ν•˜μ˜€μŠ΅λ‹ˆλ‹€.
μ΄λ ‡κ²Œ ν•˜μ—¬ μ΅œλΉˆκ°’λ“€μ„ max_list에 λͺ¨μ€ ν›„ max_list의 크기가 1이라면 μ΅œλΉˆκ°’μ€ ν•˜λ‚˜μ΄λ―€λ‘œ max_list[0]을 좜λ ₯, max_list의 크기가 1보닀 크닀면 μ΅œλΉˆκ°’μ΄ μ—¬λŸ¬κ°œμ΄λ―€λ‘œ max_list[1]을 좜λ ₯ν•˜λŠ” μ‹μœΌλ‘œ ν•΄κ²°ν•˜μ˜€μŠ΅λ‹ˆλ‹€.

λ§ˆμ§€λ§‰ rangeλŠ” μž…λ ₯ 받은 μˆ˜κ°€ μ˜€λ¦„μ°¨μˆœ μ •λ ¬λ˜μ–΄μžˆκΈ° λ•Œλ¬Έμ— 제일 큰 κ°’- 제일 μž‘μ€ 값을 ν•˜μ—¬ κ΅¬ν•΄μ£Όμ—ˆμŠ΅λ‹ˆλ‹€!!>.<

μ•— 그리고 26번째 쀄에 count == Maxκ°€ μžˆλŠ”λ° 잘λͺ»λμ–΄μš”..! count[k] == Maxκ°€ λ§žλ„€μš”
μˆ˜μ •ν•˜κ³  올리면 μ €λ²ˆμ²˜λŸΌ μ΄μƒν•˜κ²Œ 꼬일 것 κ°™μ•„μ„œ.. μ—¬κΈ° μ¨μš”

Details

 N ← μž…λ ₯λ°›κΈ° (μ •μˆ˜)
 su ← 빈 리슀트
 반볡 N번:
    a. μ •μˆ˜λ₯Ό ν•œ 쀄 μž…λ ₯λ°›μ•„ μ •μˆ˜λ‘œ λ³€ν™˜ν•œ ν›„ su에 μΆ”κ°€

 su μ •λ ¬
 length ← su의 길이

 [μ‚°μˆ ν‰κ·  계산]
   total ← 0
   반볡 i = 0λΆ€ν„° length-1:
       total += su[i]
   평균값 = total // length  
   좜λ ₯(평균값)

 [쀑앙값]
   쀑앙값 = su[length // 2]
   좜λ ₯(쀑앙값)

 [μ΅œλΉˆκ°’ 계산]
   count ← 길이 8001짜리 리슀트 (0으둜 μ΄ˆκΈ°ν™”)
           (인덱슀 0 ~ 8000 β†’ κ°’ -4000 ~ 4000 λŒ€μ‘)
   반볡 ch in su:
       count[ch + 4000] += 1

   max_list ← 빈 리슀트
   Max ← count λ¦¬μŠ€νŠΈμ—μ„œ μ΅œλŒ€κ°’

   반볡 k = 0λΆ€ν„° 8000:
       λ§Œμ•½ count[k] == Max:
           max_list에 (k - 4000) μΆ”κ°€

   λ§Œμ•½ max_list 길이가 2 이상:
       좜λ ₯(max_list[1])  ← 두 번째둜 μž‘μ€ μ΅œλΉˆκ°’
   κ·Έ μ™Έ:
       좜λ ₯(max_list[0])  ← μœ μΌν•œ μ΅œλΉˆκ°’

 [λ²”μœ„ 좜λ ₯]
   좜λ ₯(su[length-1] - su[0])

πŸ“š μƒˆλ‘­κ²Œ μ•Œκ²Œλœ λ‚΄μš©

round() ν•¨μˆ˜ -> 반올림 ν•΄μ€Œ.
// μ—°μ‚°μž -> μ •μˆ˜ λ‚˜λˆ—μ…ˆ(μ†Œμˆ˜μ  μ΄ν•˜λŠ” λ‹€ 버림)
from μ±—μ§€ν”Όν‹°

Copy link
Member

@9kyo-hwang 9kyo-hwang left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

파이썬의 κΈ°λŠ₯을 μ΅œλŒ€ν•œ ν™œμš©ν•œ, '파이썬'λ‹΅κ²Œ μž‘μ„±λœ μ½”λ“œλ₯Ό 'νŒŒμ΄μ¨λ‹‰ν•˜λ‹€'라고 λ§ν•©λ‹ˆλ‹€.
νŒŒμ΄μ¬μ€ κ°„κ²°ν•˜κ³  νŽΈλ¦¬ν•˜κ²Œ μ½”λ“œλ₯Ό μž‘μ„±ν•  수 μžˆλ„λ‘ λ‹€μ–‘ν•œ κΈ°λŠ₯을 μ œκ³΅ν•˜λŠ”λ°μš”, μ €λŠ” μ΅œλŒ€ν•œ 파이썬의 κΈ°λŠ₯을 ν™œμš©ν•΄ κ°„κ²°ν•˜κ²Œ μ§œλŠ” 것을 λͺ©ν‘œλ‘œ ν•΄λ΄€μŠ΅λ‹ˆλ‹€.

def solution(sequence):
    N = len(sequence)
    sequence.sort()
    counts = Counter(sequence)  # μ΄ν„°λŸ¬λΈ”(리슀트) λ‚΄ μ›μ†Œλ“€μ˜ 개수λ₯Ό μ„Έμ–΄ λ”•μ…”λ„ˆλ¦¬ ν˜•νƒœλ‘œ μ €μž₯ν•΄μ£ΌλŠ” λΌμ΄λΈŒλŸ¬λ¦¬μž…λ‹ˆλ‹€.

    avg = round(sum(sequence) / N)  # sum ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•˜λ©΄ μ΄ν„°λŸ¬λΈ”μ˜ μ›μ†Œ 합을 μ‰½κ²Œ ꡬ할 수 μžˆμŠ΅λ‹ˆλ‹€
    med = sequence[N // 2]
    max_mode = max(counts.values())  # μ›μ†Œ 개수λ₯Ό μ €μž₯ν•œ λ”•μ…”λ„ˆλ¦¬μ˜ values, 즉 λΉˆλ„κ°’λ“€ 쀑 κ°€μž₯ 큰 κ°’(==μ΅œλΉˆκ°’)을 μ €μž₯ν•©λ‹ˆλ‹€
    multimode = [k for k, v in counts.items() if v == max_mode]  # λ”•μ…”λ„ˆλ¦¬λ₯Ό μˆœνšŒν•΄ μ΅œλΉˆκ°’κ³Ό λ™μΌν•œ λΉˆλ„λ₯Ό κ°€μ§„ keyκ°’, 즉 μ΅œλΉˆκ°’μ— ν•΄λ‹Ήν•˜λŠ” μ›μ†Œλ“€μ„ μ €μž₯ν•©λ‹ˆλ‹€
    mode = multimode[1] if len(multimode) > 1 else multimode[0]  # μ΅œλΉˆκ°’μ΄ μ—¬λŸ¬ 개일 경우  2번째 값을, μ•„λ‹ˆλΌλ©΄ 1번째 값을 μ΅œλΉˆκ°’μœΌλ‘œ μ„€μ •ν•©λ‹ˆλ‹€
    rng = sequence[-1] - sequence[0]  # 리슀트 맨 끝 μ›μ†Œμ™€ 첫 μ›μ†Œλ₯Ό λΉΌλ©΄ λ²”μœ„λ₯Ό ꡬ할 수 μžˆμŠ΅λ‹ˆλ‹€
    
    return (avg, med, mode, rng)


def main(input):
    sequence = [int(input()) for _ in range(int(input()))]
    print('\n'.join(map(str, solution(sequence))))
    

if __name__ == "__main__":
    from collections import Counter
    main(open(0).readline)

참고둜 Counterλ₯Ό μ‚¬μš©ν•΄ μ›μ†Œλ“€μ˜ λΉˆλ„κ°’μ„ μ €μž₯ν•˜λŠ” countsλ₯Ό μƒμ„±ν•˜κΈ° 전에, 리슀트λ₯Ό 정렬해쀬기 λ•Œλ¬Έμ— countsλŠ” μ •λ ¬λœ μ›μ†Œ μˆœμ„œλŒ€λ‘œ 값이 λ“€μ–΄μžˆμŠ΅λ‹ˆλ‹€.
첫 번째 ν…ŒμŠ€νŠΈ μΌ€μ΄μŠ€λ₯Ό 예둜 λ“€μžλ©΄

5
1
3
8
-2
2

으둜 μ£Όμ–΄μ§€λ―€λ‘œ countsλŠ” λ‹€μŒκ³Ό 같이 ν‘œν˜„λ©λ‹ˆλ‹€.

Counter({-2: 1, 1: 1, 2: 1, 3: 1, 8: 1})

Copy link
Collaborator

@caucsejunseo caucsejunseo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

μ‰¬μ›Œλ³΄μ˜€λŠ”λ° μ΅œλΉˆκ°’μ—μ„œ ν—€λ§€κ²Œ λ˜λ„€μš”. λ™μœ€λ‹˜ μˆ˜λ„μ½”λ“œλ³΄κ³  ν•΄κ²°ν–ˆμŠ΅λ‹ˆλ‹€! 인덱슀λ₯Ό 8001κΉŒμ§€ ν•œλ‹€λŠ” λ°œμƒμ΄ μƒˆλ‘­λ„€μš”. Cμ–Έμ–΄λ‘œ μ΅œλΉˆκ°’ λΆ€λΆ„λ§Œ κ΅¬ν˜„ν•΄λ΄€λŠ”λ° λ°œμƒ μžμ²΄κ°€ λ™μœ€λ‹˜κ³Ό λ˜‘κ°™μ€ 것 κ°™μŠ΅λ‹ˆλ‹€

#define MAX 8001
for (int i = 0; i < N; i++) {
count[arr[i] + OFFSET]++;
}
 int modeMax = 0;
    int mode = 0;
    int modeCount = 0;

    for (int i = 0; i < MAX; i++) {
        if (count[i] > modeMax) {
            modeMax = count[i];
        }
    }```

@froglike6
Copy link
Collaborator

저도 파이썬의 κΈ°λŠ₯을 ν™œμš©ν•΄μ„œ 문제λ₯Ό ν’€μ–΄λ΄€μŠ΅λ‹ˆλ‹€. collections에 λ§Žμ€ κΈ°λŠ₯듀이 μžˆμ–΄μ„œ 이 쀑 Counterλ₯Ό μ‚¬μš©ν–ˆμŠ΅λ‹ˆλ‹€. ν’€λ‹€ λ³΄λ‹ˆ μ½”λ“œκ°€ λΉ„μŠ·ν•΄μ‘Œλ„€μš” γ…Žγ…Ž

from collections import Counter
import sys
input = sys.stdin.readline

n = int(input())
n_list = [int(input()) for _ in range(n)]

print(round(sum(n_list)/n))
print(sorted(n_list)[n//2])
c = Counter(n_list)
ms = [k for k, v in c.items() if v == max(c.values())]
ms.sort()
print(ms[1] if len(ms) > 1 else ms[0])
print(max(n_list)-min(n_list))

Copy link
Contributor

@dohyeondol1 dohyeondol1 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

μ €λ²ˆ ν•™κΈ° λ•Œ 톡계학을 λ°°μ› μ–΄μ„œ κ·Έλ‚˜λ§ˆ μ‰½κ²Œ ν’€ 수 μžˆμ—ˆμ”λ‹ˆλ‹€

저도 λ™μœ€λ‹˜κ³Ό λ§ˆμ°¬κ°€μ§€λ‘œ 배열에 λ‹΄κ³ μž
(음수 μΈλ±μŠ€λŠ” λΆˆκ°€λŠ₯ν•˜κ³ , μ •μˆ˜μ˜ μ ˆλŒ“κ°’μ΄ 4000을 λ„˜μ§€ μ•ŠμœΌλ―€λ‘œ)
-4000 ~ 4000 을 담을 수 μžˆλŠ” 배열을 μ‚¬μš©ν–ˆμŠ΅λ‹ˆλ‹€.

C++
#include <iostream>
#include <vector>
#include <cmath>
#include <algorithm>
using namespace std;

int main() {
    int N;
    cin >> N;

    vector<int> num(N);
    int sum = 0;
    vector<int> count(8001, 0);

    for(int i = 0; i < N; i++) {
        cin >> num[i];
        sum += num[i];
        count[num[i] + 4000]++;
    }

    sort(num.begin(), num.end());

    int arithmeticMean = round((double)sum / N);

    int median = num[N / 2];

    int maxCount = 0;
    int mode = 0;
    bool second = false;

    for(int i = 0; i <= 8000; i++) {
        if(count[i] > maxCount) {
            maxCount = count[i];
            mode = i - 4000;
            second = false;
        } else if(count[i] == maxCount && !second) {
            mode = i - 4000;
            second = true;
        }
    }

    int range = num.back() - num.front();

    cout << arithmeticMean << "\n";
    cout << median << "\n";
    cout << mode << "\n";
    cout << range << "\n";

    return 0;
}

ν•œκΈ€λ‘œ 코딩블둝을 μž‘μ„±ν•΄λ„ μ–Έμ–΄λ₯Ό μ§€μ •ν•΄μ£Όλ©΄ 색을 μž…ν˜€μ£ΌλŠ”κ±΄ 처음 μ•Œμ•˜μŠ΅λ‹ˆλ‹€..μ†Œμ†Œν•œ 팁 κ°€μ Έκ°€μš”μž‡~~~

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants