하루 한 접시
[백준] 28279번: 덱 2 [C#]
NaZZU
2024. 5. 20. 23:51
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
141
142
143
144
145
146
147
148
149
150
151
152
153
|
using System.IO;
using System.Text;
using System.Linq;
using System.Reflection.PortableExecutable;
using System.Security.Cryptography;
namespace 연습장
{
internal class Program
{
static void Main(string[] args)
{
using var reader = new StreamReader(Console.OpenStandardInput());
using var print = new StreamWriter(Console.OpenStandardOutput());
_28279_boj boj = new _28279_boj();
boj.boj_28279();
}
}
internal class _28279_boj
{
public void boj_28279()
{
StringBuilder sb = new StringBuilder();
Deque deque = new Deque();
deque.n = int.Parse(Console.ReadLine()) + 1; // 덱이 가득 찼는지 판별
하기 위해 빈공간을 하나 사용하므로 하나만큼 공간을 더 주었다. (n번동안 push만 할 경우 에러 방지) deque.deque = new string[deque.n];
for (int i = 0;i < deque.n - 1; i++)
{
string[] input = Console.ReadLine().Split();
switch(input[0])
{
case "1":
deque.PushFront(input[1]);
break;
case "2":
deque.PushBack(input[1]);
break;
case "3":
sb.Append(deque.PopFront() + "\n");
break;
case "4":
sb.Append(deque.PopBack() + "\n");
break;
case "5":
sb.Append(deque.size + "\n");
break;
case "6":
sb.Append(deque.IsDequeEmpty() ? "1\n" : "0\n");
break;
case "7":
sb.Append(deque.Bottom() + "\n");
break;
case "8":
sb.Append(deque.peek() + "\n");
break;
}
}
Console.Write(sb);
}
}
public class Deque
{
public int n; // 덱의 크기를 결정하는 변수
public string[] deque; // 덱을 구현할 배열
public int back = -1; // 가장 뒤에있는 숫자의 주소를 가리킬 변수
public int front = 0; // 가장 앞에있는 숫자의 주소를 가리킬 변수
public int size = 0; // 덱의 원소의 수를 저장하는 변수
public void PushFront(string data)
{
if (IsDequeFull())
return;
front = (front - 1 + n) % n; // 0 - 1 + n을 n으로 나누면 n - 1이 나온다 (다음 회차엔 n - 2, n - 3 ...)
deque[front] = data;
size++;
}
public void PushBack(string data)
{
if (IsDequeFull())
return;
back = (back + 1) % n;
deque[back] = data;
size++;
}
public bool IsDequeEmpty()
{
bool res = false;
if ((back + 1) % n == front)
res = true;
return res;
}
public bool IsDequeFull()
{
bool res = false;
if ((back + 2) % n == front)
res = true;
return res;
}
public string PopFront()
{
string res = "-1";
if (IsDequeEmpty())
return res;
res = deque[front];
deque[front] = null;
front = (front + 1) % n;
size--;
return res;
}
public string PopBack()
{
string res = "-1";
if (IsDequeEmpty())
return res;
if (back == -1) // 이 코드가 없으면 PushBack 메소드를 진행하지 않고 PopBack 메소드를 실행할 때 에러가 남
back = n - 1; // 어차피 PushBack을 실행한 적이 없다면 가장 뒤에있는 원소의 주소는 n - 1
res = deque[back];
deque[back] = null;
back = (back - 1 + n) % n;
size--;
return res;
}
public string Bottom()
{
string res = "-1";
if (IsDequeEmpty())
return res;
res = deque[front];
return res;
}
public string peek()
{
string res = "-1";
if (IsDequeEmpty())
return res;
if (back == -1)
{
res = deque[n - 1];
return res;
}
res = deque[back];
return res;
}
}
}
|
cs |
은근히 어려웠다...
덱을 구현하기 위해 원형 큐를 응용한 것까지는 좋았지만, 큐처럼 front는 항상 빈공간(null)을 가리키려고 해서 더욱 헷갈렸던 것 같다.