[c#]백준 알고리즘 10845 - 큐
이제 구현 파트에서 자료구조 파트를 넘어가는 시기가 되었다. 이제 코드를 구조적으로 구현 할 수있다는 생각을 하니 조금은 뿌듯하다. C#에서 큐 클래스가 이미 구현되어있기 때문에 큐 클래스를 사용하여 풀었다.
밑에는 큐 구현 및 메소드를 정리한 포스트이다.
큐( queue )의 구현과 메소드 사용 [C#]
큐 ( queue ) 요소가 한쪽 끝(후면)에서 추가되고 다른 쪽 끝(전면)에서 제거되는 요소 컬렉션을 나타내는 추상 데이터 유형 대기열은 FIFO(First In First Out,선입선출) 원칙을 따른다. 즉, 먼저 추가된
rnflajdrnfl.tistory.com
문제
정수를 저장하는 큐를 구현한 다음, 입력으로 주어지는 명령을 처리하는 프로그램을 작성하시오.
명령은 총 여섯 가지이다.
push X: 정수 X를 큐에 넣는 연산이다.
pop: 큐에서 가장 앞에 있는 정수를 빼고, 그 수를 출력한다. 만약 큐에 들어있는 정수가 없는 경우에는 -1을 출력한다.
size: 큐에 들어있는 정수의 개수를 출력한다.
empty: 큐가 비어있으면 1, 아니면 0을 출력한다.
front: 큐의 가장 앞에 있는 정수를 출력한다. 만약 큐에 들어있는 정수가 없는 경우에는 -1을 출력한다.
back: 큐의 가장 뒤에 있는 정수를 출력한다. 만약 큐에 들어있는 정수가 없는 경우에는 -1을 출력한다.
입력
첫째 줄에 주어지는 명령의 수 N (1 ≤ N ≤ 10,000)이 주어진다. 둘째 줄부터 N개의 줄에는 명령이 하나씩 주어진다. 주어지는 정수는 1보다 크거나 같고, 100,000보다 작거나 같다. 문제에 나와있지 않은 명령이 주어지는 경우는 없다.
출력
출력해야하는 명령이 주어질 때마다, 한 줄에 하나씩 출력한다.
문제풀이
C#언어를 사용하는 개발자로써 백준알고리즘의 조건은 오해의 소지가 많다. 그 이유는 두번째 풀이를 하면서 말을 해보겟다. 첫번재로 아래와 같이 코드를 작성해보았다.
첫 번째 풀이(시간 초과)
코드
int test_case = int.Parse(Console.ReadLine());
Queue<int> q = new Queue<int>();
for (int i = 0; i < test_case; i++)
{
string[] arr = Console.ReadLine().Split();
switch (arr[0])
{
case "push":
q.Enqueue(int.Parse(arr[1]));
break;
case "pop":
if (q.Count > 0)
Console.WriteLine(q.Dequeue());
else
Console.WriteLine(-1);
break;
case "size":
Console.WriteLine(q.Count);
break;
case "empty":
if (q.Count == 0)
Console.WriteLine(1);
else
Console.WriteLine(0);
break;
case "front":
if (q.Count > 0)
Console.WriteLine(q.Peek());
else
Console.WriteLine(-1);
break;
case "back":
if (q.Count > 0)
Console.WriteLine(q.Last());
else
Console.WriteLine(-1);
break;
}
}
출력결과
시간초과가 나왔다. 0.5초의 시간제한인 만큼 쉽지 않을 거라 생각했는데 최적화 하는 방법을 아무리 생각해도 생각이나질 않았다. 출력 조건이 "명령이 주어질 때마다, 한 줄에 하나씩 출력한다." 였기 때문에 여러번의 시행착오를 겪었다.
성공을 하고 나서 알게 된 것은 출력조건에 "명령이 주어질때 마다" 이 조건은 필요 없는 듯하다. 그냥 "한 줄에 하나씩만 출력한다"는 조건만 만족하면 되는 듯하였다. 즉 반복문이 돌아갈때 마다 출력을 하는게아니라 아래 사진처럼 반복문이 다 돌아가고 나서(입력값들만 먼저 읽는 것) 출력 값만 따로 한줄씩 출력해도 성공이라는 말이다.
그래서 출력을 할때 버퍼를 사용하는 StringBuilder 클래스를 사용하였다.
두 번째 풀이(성공)
int test_case = int.Parse(Console.ReadLine());
Queue<string> q = new Queue<string>();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < test_case; i++)
{
string[] arr = Console.ReadLine().Split();
switch (arr[0])
{
case "push":
q.Enqueue(arr[1]);
break;
case "pop":
if (q.Count > 0)
sb.AppendLine(q.Dequeue());
else
sb.AppendLine("-1");
break;
case "size":
sb.AppendLine(q.Count.ToString());
break;
case "empty":
if (q.Count == 0)
sb.AppendLine("1");
else
sb.AppendLine("0");
break;
case "front":
if (q.Count > 0)
sb.AppendLine(q.Peek());
else
sb.AppendLine("-1");
break;
case "back":
if (q.Count > 0)
sb.AppendLine(q.Last());
else
sb.AppendLine("-1");
break;
}
}
Console.Write(sb.ToString());