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

코드설명

큐(Queue) + 문자열(String)을 활용합니다.

 

문제에서 처음에는 HashMap을 활용해 들어온 순서대로 우선순위를 처리해야하나? 하지만 단어가 겹칠 수 있으므로 단어의 순서를 나타내는 HashMap을 그것으로 관리해야할까? 라는 고민이 들었습니다.

 

하지만, 위와 같은 방식보다 단순히 선입선출의 구조를 이용해 큐를 활용하면 문제가 훨씬 간단해집니다.

문제를 읽어보면, 각 단어가 주어진 문자열의 "순서대로" 처리되어야 한다는 것을 알 수 있습니다.

이러한 특성을 이해하면 되겠지요.

 

시간복잡도가 걱정될 수 있습니다. 시간복잡도는 O(N) * O(L의 단어개수) 로 총 10^7 입니다. 그러므로 시간복잡도는 안전합니다. 

 

문제에서 "Impossible"을 출력하는 과정에 대해 명확히 해보면,

1. 큐에 남은 문자열이 없어야 한다. (즉, 앵무새가 말한 모든 단어를 순서대로 받아적었다.)

2. 자신이 더 많이 작성했으면 안된다. (즉, 앵무새가 말한적 없는 단어를 초과해서 작성하면 안된다. 이 때문에 단순히 Queue에 값이 비었는지 비어있지 않은지로 판단하면 안됩니다.)

코드

정답코드1입니다.

package Main;
 
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;
 
public class Main {
	static int N, M, S, P, A, B, X, L, R, C, n, k, m, l, K, D, T;
	static int answer = 0;
	static StringBuilder sb = new StringBuilder();
	static Queue<String>[] q = new LinkedList[101];
	public static void main(String[] args) throws IOException{
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st = new StringTokenizer(br.readLine());
		
		for(int i=0; i<101; i++) {
			q[i] = new LinkedList<String>();
		}
		
		N = Integer.parseInt(st.nextToken());
		for(int i=0; i<N; i++) {
			String str = br.readLine();
			String[] split = str.split(" ");
			
			for(int j=0; j<split.length; j++) {
				q[i].add(split[j]);
			}
		}
		
		String L = br.readLine();
		String[] split = L.split(" ");
		boolean wholeFlag = true;
		for(int i=0; i<split.length; i++) {
			boolean successFlag = false;
			for(int j=0; j<N; j++) {
				if(!q[j].isEmpty() && q[j].peek().equals(split[i])) { //만약 일치한다면, 
					q[j].poll();
					successFlag = true;
					break;
				}
			}
			
			if(successFlag == false) {
				wholeFlag = false;
				break;
			}
		}
		
		 // 모든 앵무새의 큐가 비어있는지 확인
        for(int i=0; i<N; i++) {
            if(!q[i].isEmpty()) {
                wholeFlag = false;
                break;
            }
        }
        
		if(wholeFlag == true) System.out.println("Possible");
		else System.out.println("Impossible");
		
	}

}

 

처음 오답코드입니다.

정답코드1과 무엇이 다를까요? 바로 모든 앵무새의 큐가 비어있는지 확인하는 과정입니다.

만약, 모든 앵무새가 말한 단어들을 제대로 받아적지 못한 경우에도 올바른 경우가 아닌 것 입니다.

package Main;
 
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;
 
public class Main {
	static int N, M, S, P, A, B, X, L, R, C, n, k, m, l, K, D, T;
	static int answer = 0;
	static StringBuilder sb = new StringBuilder();
	static Queue<String>[] q = new LinkedList[101];
	public static void main(String[] args) throws IOException{
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st = new StringTokenizer(br.readLine());
		
		for(int i=0; i<101; i++) {
			q[i] = new LinkedList<String>();
		}
		
		N = Integer.parseInt(st.nextToken());
		for(int i=0; i<N; i++) {
			String str = br.readLine();
			String[] split = str.split(" ");
			
			for(int j=0; j<split.length; j++) {
				q[i].add(split[j]);
			}
		}
		
		String L = br.readLine();
		String[] split = L.split(" ");
		boolean wholeFlag = true;
		for(int i=0; i<split.length; i++) {
			boolean successFlag = false;
			for(int j=0; j<N; j++) {
				if(!q[j].isEmpty() && q[j].peek().equals(split[i])) { //만약 일치한다면, 
					q[j].poll();
					successFlag = true;
					break;
				}
			}
			
			if(successFlag == false) {
				wholeFlag = false;
				break;
			}
		}
        
		if(wholeFlag == true) System.out.println("Possible");
		else System.out.println("Impossible");
		
	}

}

+ Recent posts