[1158] : 요세푸스
https://www.acmicpc.net/problem/1158
1158번: 요세푸스 문제
첫째 줄에 N과 K가 빈 칸을 사이에 두고 순서대로 주어진다. (1 ≤ K ≤ N ≤ 5,000)
www.acmicpc.net
🤢고난과 역경
- 나는 연결 리스트를 복습하기 위해 이 문제를 시도해보았다.
- 처음에는 원형리스트로 구현해보았지만, 너무 코드가 복잡해져 반례가 계속 계속 나타났고... 굉장히 비효율적인 코드 때문에 시간 초과까지 나왔다. 심지어 내 코드는 나도 못 알아볼 정도로 복잡하고 쓰레기였다..!
- 그래서 이중연결리스트로 바꿔보았고 이 문제에서는 시작 지점이 매번 바뀌어야 하니 head와 tail을 전역 변수로 두고 시작 위치를 head에 저장하며 delete 함수를 작성했다.
💻코드 [C언어]
//1158 - 요세푸스/이중연결리스트
#include <stdio.h>
#include <stdlib.h>
typedef int element;
typedef struct DListNode {
struct DListNode* next;
struct DListNode* pre;
element data;
}Node;
Node* head = NULL;
Node* tail = NULL;
void insert(element data) {
Node* newNode = (Node*)malloc(sizeof(Node));
newNode->data = data;
if (head == NULL) { //노드가 하나도 없을 때
head = newNode;
tail = newNode;
newNode->pre = head;
newNode->next = tail;
}
else {
tail->next = newNode;
newNode->pre = tail;
head->pre = newNode;
newNode->next = head;
tail = newNode;
}
}
int delete_pos(int pos) {
Node* p = head;
if (head == NULL) return 0;
while (--pos) {
p = p->next;
}
head = p->next; //다음 시작지점 저장
p->pre->next = p->next;
p->next->pre = p->pre;
return p->data;
}
int main(void) {
int n, k;
scanf_s("%d %d", &n, &k);
for (int i = 1; i <= n; i++) {
insert(i);
}
printf("<");
for (int i = 0; i < n - 1; i++) {
printf("%d, ", delete_pos(k));
}
printf("%d", delete_pos(k));
printf(">");
return 0;
}
🎁느낀 점
- 시간초과를 막기 위해 이중 반복문은 절대 쓰면 안 되겠다고 느꼈다...
- 그리고 다른 사람들의 코드도 많이 관찰해보며 어떻게하면 효율적이고 좋은 코드를 짤 수 있는지 노력해야겠다.
'Coding > BOJ[C]' 카테고리의 다른 글
[백준][C] 1062-가르침/Brute Force/브루트 포스/비트 마스킹/조합/재귀/백트래킹/DFS (0) | 2021.08.09 |
---|---|
[백준][C] 1260-DFS와 BFS/인접리스트/그래프/깊이우선탐색/넓이우선탐색 (0) | 2021.08.03 |
[백준][C] 2751-수 정렬하기 2/정렬/mergeSort/합병정렬 (0) | 2021.07.24 |
[백준][C] 2164-카드2/원형 큐/QUEUE (0) | 2021.07.22 |
[백준][C] 2504-괄호의 값/스택 (0) | 2021.07.18 |