하루하루 꾸준히, 인생은 되는대로

자료구조

백준 2164번 c언어

긤효중 2021. 9. 23. 08:52

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

 

2164번: 카드2

N장의 카드가 있다. 각각의 카드는 차례로 1부터 N까지의 번호가 붙어 있으며, 1번 카드가 제일 위에, N번 카드가 제일 아래인 상태로 순서대로 카드가 놓여 있다. 이제 다음과 같은 동작을 카드가

www.acmicpc.net

 

문제

N장의 카드가 있다. 각각의 카드는 차례로 1부터 N까지의 번호가 붙어 있으며, 1번 카드가 제일 위에, N번 카드가 제일 아래인 상태로 순서대로 카드가 놓여 있다.

이제 다음과 같은 동작을 카드가 한 장 남을 때까지 반복하게 된다. 우선, 제일 위에 있는 카드를 바닥에 버린다. 그 다음, 제일 위에 있는 카드를 제일 아래에 있는 카드 밑으로 옮긴다.

예를 들어 N=4인 경우를 생각해 보자. 카드는 제일 위에서부터 1234 의 순서로 놓여있다. 1을 버리면 234가 남는다. 여기서 2를 제일 아래로 옮기면 342가 된다. 3을 버리면 42가 되고, 4를 밑으로 옮기면 24가 된다. 마지막으로 2를 버리고 나면, 남는 카드는 4가 된다.

N이 주어졌을 때, 제일 마지막에 남게 되는 카드를 구하는 프로그램을 작성하시오.


 

입력

첫째 줄에 정수 N(1 ≤ N ≤ 500,000)이 주어진다.


 

출력

첫째 줄에 남게 되는 카드의 번호를 출력한다.


 

해결방안 -> n이 4일때 생각을 해보면 먼저 1부터 n까지 큐에 Push연산을 한다.

그럼 [1,2,3,4]이 상태가 되고 제일 위에 있는 카드를 바닥에 버리는 연산(Pop연산)을 수행한다.

->[2,3,4]의 상태가 된다.

그리고 2를 제일 아래로 옮겨야 하는데 , 2를 넣어주는 Push연산을 한번 하고

Pop연산을 하면 [3,4,2]의 상태가 된다.

큐의 크기가 1이되면 반복문을 탈출한다. 

n == 1일 경우는 1을 출력한다.

 

 

전체 소스 코드

#include <stdio.h>
#define True 1
#define False 0
#include<string.h>
#define LEN 1000000
typedef struct _cQueue{
    int size;//큐의 크기
    int front; //큐의 제일 앞부분(Push연산)
    int rear; //큐의 맨 뒷부분(Pop연산)
    int arr[LEN];
}CQUEUE; //큐의 구조체 정의
 
typedef CQUEUE Queue;
 
void Queueinit(Queue *pq){ //큐 초기화
    pq->front = 0;
    pq->rear = 0;
    pq->size = 0;
}
int Empty(Queue *pq){ //비어있으면 참 아니면 거짓
    if(pq->front == pq->rear){
        return True;
    }
    else{
        return False;
    }
}
 
int Nextindex(int pos){ //Push,Pop시 변수를 이동시켜주는 함수, 큐의 끝에 도달하면 인덱스 0으로 바꾸기
    if(pos == LEN - 1 ){
        return 0;
    }
    else{
        return pos = pos + 1;
    }
}
int Front(Queue *pq){ //front인덱스의 값 반환
    if(Empty(pq)){
        return -1;
    }
    else{
        return pq->arr[pq->front+1];
    }
}
 
int Back(Queue *pq){//rear인덱스의 값 반환
    if(Empty(pq)){
        return -1;
    }
    else{
        return pq->arr[pq->rear];
    }
}
 
int Size(Queue *pq){//큐의 크기
    if(Empty(pq)){
        return 0;
    }else{
    return pq->size;
}}
 
void Push(Queue *pq,int data){ //rear을 1 증가시키고 데이터를 넣는다 + 큐의 크기 1 증가시킨다.
    pq->rear = Nextindex(pq->rear);
    pq->arr[pq->rear] = data;
    pq->size = pq->size + 1;
}
 
void Pop(Queue *pq){ //front를 1 증가시키고 큐의 크기를 1 감소시킨다.
    if(Empty(pq)){
        return -1;
    }
    else{
        pq->size = pq->size - 1;
        pq->front = Nextindex(pq->front);
 
    }
}
 
int main(void){
    int n;
    scanf("%d",&n);
    Queue q;
    Queueinit(&q); //큐의 생성과 초기화
    for(int i = 0;i<n;i++){
    Push(&q,i+1); //n까지 Push연산
    }
    while(n>=2){ //n이 2이상일때
        Pop(&q); 
        if(Size(&q) == 1) //큐의 크기가 1이면 루프 탈출
            break;
        Push(&q,Front(&q)); //front인덱스의 값을 Push연산시킨다.
        Pop(&q);
    }
    if(n == 1){ //n이 1이면 1출력
     printf("1");}
     else{ //아니면 front인덱스의 값을 출력한다
         printf("%d",Front(&q));
     }
    
 
}

'자료구조' 카테고리의 다른 글

백준 3986번 C언어  (0) 2021.09.27
백준 2822 C언어  (0) 2021.09.25
백준 11899번 C언어  (0) 2021.09.19
백준 4949번 C언어  (0) 2021.09.17
큐의 개념 + 백준 10845 C언어  (0) 2021.09.16