반응형
카드1 문제 링크
카드2 문제 링크
어떻게 풀까?
두 문제는 N만 다르지 거의 같은 문제입니다!
두 문제를 풀기 위해 리스트를 사용했습니다.
카드 1의 경우에는 리스트에서 맨 앞에 하나는 출력하고 리스트에서 삭제합니다.
그리고 또다시 맨 앞의 수를 삭제하고 맨 뒤에 넣습니다.
이 행동을 n-1번 반복하면 마지막 카드가 남고, 이 카드를 출력해주면 됩니다!
예제를 한번 풀어보겠습니다!
처음에 리스트에는 1,2,3,4,5,6,7이 들어있습니다.
맨 앞에있는 수는 출력하고, 2는 삭제한 뒤에 맨 뒤에 다시 넣어줍니다.
이제 맨 앞의 수가 3이 되고, 해당 수를 출력하고 삭제합니다.
4는 삭제하고 맨 뒤로 보냅니다.
이제 맨 앞의 수는 7이 됩니다. 7을 출력하고 리스트에서 삭제합니다.
2도 리스트에서 삭제 후에 맨 뒤에 다시 넣어줍니다.
이제 4번이 리스트의 맨 앞에 오게 됩니다.
6은 리스트에서 삭제후 다시 맨 뒤에 넣어줍니다.
이제 2를 출력하고 삭제합니다.
마지막으로 6을 출력하면 완성됩니다!
카드 2번의 경우는 더 간단합니다.
카드 1에서 했던 행동에서 맨 앞에 하나를 출력하고 리스트를 삭제하는 부분에서 출력만 안하면 됩니다.
즉, 카드 2의 경우에는 리스트에서 맨 앞에 하나는 리스트에서 삭제하고, 맨 뒤의 리스트는 삭제한 뒤에 다시 맨 뒤에 넣어주면 됩니다.
코드(카드 1)
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 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 | #pragma once #include<cstdio> struct NODE { int value; NODE* prev; NODE* next; NODE() { prev = next = 0; } }; static struct MYMAL { NODE nodes[10000]; int idx; MYMAL() { idx = 0; } void clear() { idx = 0; } NODE* malloc() { return &nodes[idx++]; } } MYMAL; struct LIST { NODE *head, *tail; NODE *cursor[2]; LIST() { head = MYMAL.malloc(); tail = MYMAL.malloc(); head->next = tail; tail->prev = head; } void insert_front(int i) { NODE *nn = MYMAL.malloc(); nn->value = i; nn->next = head->next; nn->prev = head; head->next->prev = nn; head->next = nn; } void insert_back(int i) { NODE* nn = MYMAL.malloc(); nn->value = i; nn->next = tail; nn->prev = tail->prev; tail->prev->next = nn; tail->prev = nn; } void clear_front() { cursor[0] = head; } void clear_back() { cursor[1] = tail; } int next() { if(cursor[0]->next != tail) cursor[0] = cursor[0]->next; return cursor[0]->value; } int prev() { if (cursor[1]->prev != head) cursor[1] = cursor[1]->prev; return cursor[1]->value; } void del_front() { if (cursor[0] != head) { cursor[0]->prev->next = cursor[0]->next; cursor[0]->next->prev = cursor[0]->prev; cursor[0] = cursor[0]->prev; } } void del_back() { if (cursor[1] != tail) { cursor[1]->prev->next = cursor[1]->next; cursor[1]->next->prev = cursor[1]->prev; cursor[1] = cursor[1]->next; } } }; int main() { int n; scanf("%d\n", &n); LIST li; for (int i = 1; i <= n; i++) { li.insert_back(i); } li.clear_back(); li.clear_front(); for (int i = 1; i < n; i++) { int out = li.next(); printf("%d ", out); li.del_front(); out = li.next(); li.del_front(); li.insert_back(out); } printf("%d\n", li.next()); return 0; } | cs |
코드(카드 2)
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 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 | #pragma once #include<cstdio> struct NODE { int value; NODE* prev; NODE* next; NODE() { prev = next = 0; } }; //malloc을 쓰기 싫었음. static struct MYMAL { NODE nodes[2000000]; int idx; MYMAL() { idx = 0; } void clear() { idx = 0; } NODE* malloc() { return &nodes[idx++]; } } MYMAL; struct LIST { NODE *head, *tail; NODE *cursor[2]; LIST() { head = MYMAL.malloc(); tail = MYMAL.malloc(); head->next = tail; tail->prev = head; } void insert_front(int i) { NODE *nn = MYMAL.malloc(); nn->value = i; nn->next = head->next; nn->prev = head; head->next->prev = nn; head->next = nn; } void insert_back(int i) { NODE* nn = MYMAL.malloc(); nn->value = i; nn->next = tail; nn->prev = tail->prev; tail->prev->next = nn; tail->prev = nn; } void clear_front() { cursor[0] = head; } void clear_back() { cursor[1] = tail; } int next() { if(cursor[0]->next != tail) cursor[0] = cursor[0]->next; return cursor[0]->value; } int prev() { if (cursor[1]->prev != head) cursor[1] = cursor[1]->prev; return cursor[1]->value; } void del_front() { if (cursor[0] != head) { cursor[0]->prev->next = cursor[0]->next; cursor[0]->next->prev = cursor[0]->prev; cursor[0] = cursor[0]->prev; } } void del_back() { if (cursor[1] != tail) { cursor[1]->prev->next = cursor[1]->next; cursor[1]->next->prev = cursor[1]->prev; cursor[1] = cursor[1]->next; } } }; int main() { int n; scanf("%d\n", &n); LIST li; for (int i = 1; i <= n; i++) { li.insert_back(i); } li.clear_back(); li.clear_front(); for (int i = 1; i < n; i++) { int out = li.next(); li.del_front(); out = li.next(); li.del_front(); li.insert_back(out); } printf("%d\n", li.next()); return 0; } | cs |
여담
시간 복잡도는 어떻게 될까요!?
리스트에 넣고 빼는 일을 n번 반복하므로, 두 문제 모두 시간복잡도는 O(n)입니다.
반응형
'공부 > 알고리즘 문제풀이' 카테고리의 다른 글
[알고스팟] 실험 데이터 복구하기 (0) | 2018.07.04 |
---|---|
[BOJ] 1158번 조세퍼스 문제 (0) | 2018.07.02 |
[알고스팟] 웨브바짐 (2) | 2018.07.02 |
[SW Expert Academy] 괄호 짝짓기 (0) | 2018.07.01 |
[SW Expert Academy] 길찾기 (0) | 2018.07.01 |