Skip to content

Conversation

@dohyeondol1
Copy link
Contributor

@dohyeondol1 dohyeondol1 commented Apr 12, 2025

πŸ”— 문제 링크

νšŒμ „ν•˜λŠ” 큐

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

40λΆ„

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

μ–‘λ°©ν–₯ 큐라고 λ³Ό 수 μžˆλŠ” '덱(deque)' 자료ꡬ쑰λ₯Ό 톡해 μ‰½κ²Œ ν’€ 수 μžˆλŠ” λ¬Έμ œμ˜€μŠ΅λ‹ˆλ‹€.
덱을 λͺ°λžλ‹€ ν•˜λ”λΌλ„ ν’€ μˆ˜μ•Ό μžˆκ² λ”λΌκ΅¬μš”..

μ£Όμ–΄μ§„ μž…λ ₯ μˆœμ„œλŒ€λ‘œ 수λ₯Ό 뽑아내야 ν•˜κΈ° λ•Œλ¬Έμ—,
μ—°μ‚° 횟수둜 μΉ˜μ§€ μ•ŠλŠ” 1번 연산을 μ΄μš©ν•œλ‹΅μ‹œκ³  λ¬΄μž‘μ • 수λ₯Ό λ½‘μ•„λ‚΄κΈ°λ§Œ ν•΄μ„œλŠ” 닡을 λ„μΆœν•  수 μ—†μŠ΅λ‹ˆλ‹€.

μ£Όμ–΄μ§„ μˆ˜κ°€ λ±μ—μ„œ μ•ž(μ™Όμͺ½), λ’€(였λ₯Έμͺ½) 쀑 어디에 더 κ°€κΉŒμš΄μ§€ νŒλ³„ν•˜κ³ ,
κ°€κΉŒμš΄ μͺ½μœΌλ‘œ 수λ₯Ό ν•œ μΉΈμ”© μ΄λ™μ‹œμΌœ λμžλ¦¬μ—μ„œ 뽑아내야 ν•©λ‹ˆλ‹€.

어디에 κ°€κΉŒμš΄μ§€λŠ”
덱 크기의 절반(쀑간지점)κ³Ό, ν•΄λ‹Ή μˆ˜κ°€ μœ„μΉ˜ν•œ 인덱슀의 λŒ€μ†Œ 비ꡐλ₯Ό 톡해 νŒλ³„ν•˜μ˜€μŠ΅λ‹ˆλ‹€.
덱 크기의 μ ˆλ°˜λ³΄λ‹€ μΈλ±μŠ€κ°€ μž‘λ‹€λ©΄ μ•ž(μ™Όμͺ½)에 μœ„μΉ˜ν•œ 것이고, μ•„λ‹ˆλΌλ©΄ λ’€(였λ₯Έμͺ½)에 μœ„μΉ˜ν•œ 것이겠죠?

이에 맞좰 μ—°μ‚°νšŸμˆ˜λ₯Ό 1μ”© μ¦κ°€μ‹œμΌœ μ΅œμ†Œμ—°μ‚°νšŸμˆ˜λ₯Ό λ„μΆœν•˜μ˜€μŠ΅λ‹ˆλ‹€.

μˆ˜λ„ μ½”λ“œ
μž…λ ₯: μ •μˆ˜ N, M
μž…λ ₯: 길이 M의 μ •μˆ˜ λ°°μ—΄ target

덱 dqλ₯Ό 1λΆ€ν„° NκΉŒμ§€λ‘œ μ΄ˆκΈ°ν™”

count ← 0

for i in 0λΆ€ν„° M-1κΉŒμ§€:
    ν˜„μž¬ 찾을 κ°’ = target[i]
    dqμ—μ„œ ν˜„μž¬ κ°’μ˜ 인덱슀λ₯Ό 찾음

    if 인덱슀 ≀ dq 크기의 절반: 
        // μ™Όμͺ½μœΌλ‘œ ν•œ μΉΈμ”© 이동
        인덱슀 횟수만큼:
            dq μ•ž μš”μ†Œλ₯Ό λ’€λ‘œ 보냄
            2번 μ—°μ‚° 횟수 count 증가
    else:
        // 였λ₯Έμͺ½μœΌλ‘œ ν•œ μΉΈμ”© 이동
        (dq 크기 - 인덱슀) 횟수만큼:
            dq λ’€ μš”μ†Œλ₯Ό μ•žμœΌλ‘œ 보냄
            3번 μ—°μ‚° 횟수 count 증가

    dqμ—μ„œ 맨 μ•ž μš”μ†Œ 제거 (찾은 κ°’ 제거)

좜λ ₯: count

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

덱(Deque, double-ended queue)
두 개의 포인터λ₯Ό μ‚¬μš©ν•˜μ—¬, μ–‘μͺ½μ—μ„œ μ‚­μ œμ™€ μ‚½μž…μ„ λ°œμƒμ‹œν‚¬ 수 μžˆμŠ΅λ‹ˆλ‹€.

μ‹œν—˜κΈ°κ°„μ΄λΌ PR μ“°κΈ°κ°€ 쑰금 λΉ λ“―ν•˜λ„€μš”...κ·Έλ¦Ό μžλ£ŒλŠ” κ°€λŠ₯ν•œ 빨리 좔가해보도둝 ν•˜κ² μŠ΅λ‹ˆλ‹€..

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.

deque은 μ–‘λ°©ν–₯ μž…μΆœλ ₯이 κ°€λŠ₯ν•˜λ‹€λŠ” 것 외에도, queue와 달리 iterator 기반 연산을 μ§€μ›ν•©λ‹ˆλ‹€(일반 queueλŠ” find 같은 λ©”μ„œλ“œλ₯Ό μ‚¬μš©ν•  수 μ—†μŠ΅λ‹ˆλ‹€!), κ·Έλž˜μ„œ [] μ—°μ‚°μžλ₯Ό 톡해 νŠΉμ • 인덱슀의 μ›μ†Œλ„ λ°”λ‘œ 얻을 수 μžˆλ‹€λŠ” νŠΉμ§•μ΄ 있죠.

κ·Έλ ‡λ‹€λ³΄λ‹ˆ μ €λŠ” μ–΄μ§€κ°„ν•΄μ„  queue보닀 deque을 μ„ ν˜Έν•˜κ²Œ λ˜λ„€μš” :)

#include <iostream>
#include <queue>
#include <numeric>
#include <algorithm>

using namespace std;

int main()
{
    int N, M; cin >> N >> M;
    
    deque<int> DQ(N);
    iota(DQ.begin(), DQ.end(), 1);
    
    auto LeftShift = [&DQ]()
    {
        DQ.emplace_back(DQ.front());
        DQ.pop_front();
    };
    
    auto RightShift = [&DQ]()
    {
        DQ.emplace_front(DQ.back());
        DQ.pop_back();
    };
    
    int Answer = 0;
    while(M--)
    {
        int Target; cin >> Target;
        
        int Index = find(DQ.begin(), DQ.end(), Target) - DQ.begin();
        if(Index <= DQ.size() / 2)
        {
            for(; DQ.front() != Target; Answer++)
            {
                LeftShift();
            }
        }
        else
        {
            for(; DQ.front() != Target; Answer++)
            {
                RightShift();
            }
        }
        
        DQ.pop_front();
    }
    
    cout << Answer;

    return 0;
}

Copy link
Member

Choose a reason for hiding this comment

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

널 값을 λ„˜κ²¨μ€„ 땐 κ°€λŠ₯ν•˜λ©΄ nullptr을 μ‚¬μš©ν•΄μ£Όμ„Έμš©

Copy link
Contributor Author

Choose a reason for hiding this comment

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

nullptr은 포인터λ₯Ό λͺ…ν™•νžˆ λ‚˜νƒ€λ‚΄λŠ”κ΅°μš”.. nullptr을 μ‚¬μš©ν•˜λŠ”κ±Έ μ§€ν–₯ν•΄μ•Όκ² λ„€μš₯

Comment on lines +12 to +14
Copy link
Member

Choose a reason for hiding this comment

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

μ•„μ£Ό μ‚¬μ†Œν•œ 팁? 인데

#include <numeric>

deque<int> DQ(N);
iota(DQ.begin(), DQ.end(), 1);  // 1, 2, 3, ..., N - 1, N으둜 DQκ°€ μ±„μ›Œμ§

numeric 헀더에 iotaλΌλŠ” ν•¨μˆ˜κ°€ μžˆμŠ΅λ‹ˆλ‹€. 이거λ₯Ό μ‚¬μš©ν•˜λ©΄ λ„˜κ²¨μ£ΌλŠ” 숫자(μ—¬κΈ°μ„œλŠ” 1)λΆ€ν„° 1μ”© μ¦κ°€ν•˜λŠ” κ°’μœΌλ‘œ μ±„μ›Œμ€λ‹ˆλ‹€.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

였호....!!!!! μ‚¬μ†Œν•˜μ§€λ§Œ μ–Έμ  κ°€ 써먹을 팁!! κ°μ‚¬ν•©λ‹ˆλ‹€

Comment on lines +16 to +18
Copy link
Member

Choose a reason for hiding this comment

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

사싀 이 λ¬Έμ œλŠ” μ–΄λ–€ target값을 μ‚¬μš©ν•  λ•Œ, λ‹€λ₯Έ target값은 μ•Œ ν•„μš”κ°€ μ—†κΈ° λ•Œλ¬Έμ— 배열에 미리 λ‹€ μ €μž₯해두지 μ•Šμ•„λ„ λ©λ‹ˆλ‹€.

while(M--)
{
  int target; cin >> target;
  int index = find(dq.begin(), dq.end(), target[i]) - dq.begin();

  ...
}

이런 μ‹μœΌλ‘œ μ‹€μ‹œκ°„μœΌλ‘œ target 값을 ν•˜λ‚˜μ”© 받을 λ•Œλ§ˆλ‹€ 연산을 μˆ˜ν–‰ν•˜λ„λ‘ μ½”λ“œλ₯Ό μž‘μ„±ν•΄λ„ λ¬΄λ°©ν•˜μ£  :)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

κ·Έλ ‡λ„€μš”...; λ‚˜λ¦„ κΉŽλŠ”λ‹€κ³  κΉŽμ•˜λŠ”λ° 살짝 λͺ¨μžλžλ‚˜ λ΄…λ‹ˆλ‹€..
μ›λž˜λŠ” 값을 λ°”λ‘œ μ‚¬μš© κ°€λŠ₯ν•œ 경우 λ˜λ„λ‘μ΄λ©΄ while문을 μ“°λŠ” 편인데, μ΄λ²ˆμ—” μ•Œμ•„μ°¨λ¦¬μ§€ λͺ»ν–ˆλ„€μš”..

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.

덱은 처음 λ³΄μ§€λ§Œ 큐λ₯Ό 이전에 κ³΅λΆ€ν–ˆμ–΄μ„œ μ‰½κ²Œ μ ‘ν–ˆμŠ΅λ‹ˆλ‹€! λ¬Έμ œκ°€ 처음 μ ‘ν–ˆμ„ λ•Œ ν’€κΈ° 쒋은 문제인 κ±° κ°™μ•„μš”. cμ–Έμ–΄λ‘œ 덱을 ν•œ 번 κ΅¬ν˜„ν•΄ λ΄€μŠ΄λ‹€.

C μ½”λ“œ
#define MAX 1000  // 덱 μ΅œλŒ€ 크기

typedef struct {
    int data[MAX];
    int front;
    int back;
} Deque;

// 덱 μ΄ˆκΈ°ν™”
void init(Deque* dq) {
    dq->front = dq->back = 0;
}

// 덱이 λΉ„μ—ˆλŠ”μ§€ 확인
int isEmpty(Deque* dq) {
    return dq->front == dq->back;
}

// 덱이 가득 μ°ΌλŠ”μ§€ 확인
int isFull(Deque* dq) {
    return (dq->back + 1) % MAX == dq->front;
}

// μ•žμ— μ‚½μž…
void push_front(Deque* dq, int x) {
    if (isFull(dq)) {
        printf("Deque is full!\n");
        return;
    }
    dq->front = (dq->front - 1 + MAX) % MAX;
    dq->data[dq->front] = x;
}

// 뒀에 μ‚½μž…
void push_back(Deque* dq, int x) {
    if (isFull(dq)) {
        printf("Deque is full!\n");
        return;
    }
    dq->data[dq->back] = x;
    dq->back = (dq->back + 1) % MAX;
}

// μ•žμ—μ„œ 제거
int pop_front(Deque* dq) {
    if (isEmpty(dq)) {
        printf("Deque is empty!\n");
        return -1;
    }
    int value = dq->data[dq->front];
    dq->front = (dq->front + 1) % MAX;
    return value;
}

// λ’€μ—μ„œ 제거
int pop_back(Deque* dq) {
    if (isEmpty(dq)) {
        printf("Deque is empty!\n");
        return -1;
    }
    dq->back = (dq->back - 1 + MAX) % MAX;
    return dq->data[dq->back];
}

// μ•žμ˜ κ°’ 확인
int front(Deque* dq) {
    if (isEmpty(dq)) {
        printf("Deque is empty!\n");
        return -1;
    }
    return dq->data[dq->front];
}

// λ’€μ˜ κ°’ 확인
int back(Deque* dq) {
    if (isEmpty(dq)) {
        printf("Deque is empty!\n");
        return -1;
    }
    return dq->data[(dq->back - 1 + MAX) % MAX];
}

@froglike6
Copy link
Collaborator

dequeλ₯Ό 정말 μ˜€λžœλ§Œμ— λ³΄λŠ” 것 κ°™μŠ΅λ‹ˆλ‹€.. μ €λŠ” 파이썬의 rotateλ₯Ό μ΄μš©ν•΄ 비ꡐ적 μ‰½κ²Œ ν’€μ–΄λ΄€μŠ΅λ‹ˆλ‹€.

파이썬

from collections import deque
import sys
input = sys.stdin.readline
N, M = map(int, input().split())
targets = list(map(int, input().split()))
dq = deque(range(1, N+1))
ops = 0
for t in targets:
    idx = dq.index(t)
    if idx <= len(dq) - idx:
        dq.rotate(-idx)
        ops += idx
    else:
        dq.rotate(len(dq) - idx)
        ops += len(dq) - idx
    dq.popleft()
print(ops)

@dohyeondol1
Copy link
Contributor Author

@caucsejunseo
였였 C둜 λ±κ΅¬ν˜„..!! 저도 덱을 처음 μ ‘ν•΄μ„œ 이 문제λ₯Ό κ°€μ Έμ™€λ΄€μ–΄μš” γ…Žγ…Ž
이제 μ‹œν—˜λ„ λλ‚¬λŠ”λ° μ€€μ„œλ‹˜λ„ λ‹€λ₯Έ μ–Έμ–΄λ‘œ κ°ˆμ•„νƒ€μ‹œλ‚˜μš”...??

Copy link
Collaborator

@hadongun hadongun left a comment

Choose a reason for hiding this comment

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

였우.. νŒŒμ΄μ¬μ—λŠ” 큐λ₯Ό νšŒμ „μ‹œν‚¬ 수 μžˆλŠ” rotateλΌλŠ” 게 μžˆλ”κ΅°μš”!

생각보닀 쉽지 μ•Šλ„€μš”.. ! μ—°μ‚° 횟수λ₯Ό μ–΄λ–»κ²Œ ꡬ해야 ν• κΉŒ.. 에 λŒ€ν•΄μ„œ 생각이 잘 λ‚˜μ§ˆ μ•Šμ•„
μ•½κ°„μ˜ μ§€ν”Όν‹°μ˜ 도움을 λ°›μ•˜λ„€μš₯

νŒŒμ΄λ–€

from collections import deque

n, m = map(int, input().split())
targets = list(map(int, input().split()))
rotationq = deque()
for i in range(1, n + 1):
    rotationq.append(i)

total_moves = 0

for target in targets:
    idx = rotationq.index(target)
    if idx <= len(rotationq) // 2:
        rotationq.rotate(-idx)
        total_moves += idx
    else: 
        rotationq.rotate(len(rotationq) - idx)
        total_moves += len(rotationq) - idx

    rotationq.popleft() 

print(total_moves)

@dohyeondol1
Copy link
Contributor Author

@hadongun
μŠ€νƒκ³Ό 큐에 쑰금 μ΅μˆ™ν•΄μ§€λ©΄ 덱은 μžμ—°μŠ€λŸ½κ²Œ ν’€ 수 μžˆμ„ 것 κ°™μŠ΅λ‹ˆλ‹€!
μ–‘λ°©ν–₯ 큐라고 μƒκ°ν•˜λ©΄, 사싀 큐λ₯Ό μ“Έ μ΄μœ κ°€ 쀄어듀어 λŒ€λΆ€λΆ„ 덱만 μ“Έ 것 같기도 ν•˜κ΅¬μš” γ…‹γ…‹

μ €λŠ” 개인적으둜 문제λ₯Ό ν’€λ‹€κ°€ μ•„μ˜ˆ λͺ¨λ₯΄κ² λ‹€ μ‹ΆμœΌλ©΄ λ‹€λ₯Έ μ‚¬λžŒλ“€μ˜ λΈ”λ‘œκ·Έλ₯Ό μ°Έκ³ ν•˜λŠ” νŽΈμž…λ‹ˆλ‹€..
gptν•œν…Œ λ‹€μ–‘ν•œ 풀이λ₯Ό 받을 μˆ˜λ„ μžˆκ² μ§€λ§Œ,
λ‹€λ₯Έ μ‚¬λžŒλ“€μ΄ μž‘μ„±ν•œ λ‹€μ–‘ν•œ μ ‘κ·Ό λ°©λ²•μ΄λ‚˜ μ •ν˜•ν™”λœ 방법을 직접 찾아보고 μ ‘ν•˜λŠ” 편이 μ’€ 더 재밌게 배울 수 μžˆλ”λΌκ΅¬μš”.
(μ•„λ¬΄λž˜λ„ gptλŠ” μŸμ•„λΆ€μ€ μ‹œκ°„μ΄ ν•œμˆœκ°„μ— 아무것도 μ•„λ‹Œκ²Œ λ˜μ–΄λ²„λ¦¬λŠ” 것 κ°™μ•„μ„œ ν˜„νƒ€κ°€ μ˜΅λ‹ˆλ‹€..)

μ–΄μ¨Œκ±°λ‚˜ μ΄λ²ˆμ— λ°°μ› μœΌλ‹ˆ λ‹€μŒμ— 잘 ν’€λ©΄ 되죠! λΉ λΉ λΉ μ΄νŒ…!

@dohyeondol1 dohyeondol1 merged commit 8f5c7f4 into main May 3, 2025
@dohyeondol1 dohyeondol1 deleted the 8-dohyeondol1 branch May 3, 2025 16:25
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.

6 participants