티스토리 뷰

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

 

20923번: 숫자 할리갈리 게임

첫째 줄에는 도도와 수연이가 가지는 카드의 개수 $N$($ 1 \leq N \leq 30\,000$)과 게임 진행 횟수 $M$($ 1 \leq M \leq 2\,500\,000$)이 주어진다. 둘째 줄부터 $N$개의 줄에는 띄어쓰기로 구분하여 도도와 수연

www.acmicpc.net

 

풀이

 

1) 도도의 덱(dodo), 도도의 그라운드(gD), 수연의 덱(suyun), 수연의 그라운드(gS) 총 4개의 Deque 자료구조를 선언한다.

2) 게임을 M번 진행한다. (while)

2-0) 도도부터 한장씩 자신의 그라운드에 펼친다. M--

2-1) 만약 펼칠 패가 없을경우 바로 상대방의 승리이다.

2-2) 펼칠 패가 있을경우 그라운드에 올리는데 이때 승리조건이 부합하면 승리자가 카드를 모두 가져간다. (상대것 부터)

2-3) M이 0이 될 경우 반복문 종료

3) 수연이의 턴도 2) 와 똑같이 진행한다.

4) M번 진행후 결과가 안나왔을 경우 각자 가지고 있는 덱의 크기를 비교해서 결과를 반환한다.

 

주의사항

 

1) 그라운드에서 덱으로 가져올때의 처리가 생각보다 헷갈린다. 앞으로 넣을지 뒤로 넣을지..

2) 도도와 수연이 한번씩 진행하는 것이 1턴이 아니다. 도도 1턴 수연 1턴으로 나누어져있다. <- 정말 설명을 헷갈리게 써놓았다.

 

package com.baekJoon;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StringReader;
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;

public class BJ_S1_20923_숫자할리갈리게임 {
	static BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
	static StringTokenizer tokens;
	static int N,M;
	public static void main(String[] args) throws NumberFormatException, IOException {
		input = new BufferedReader(new StringReader(src));
		Deque<Integer> dodo = new LinkedList<>();
		Deque<Integer> suyun = new LinkedList<>();
		Deque<Integer> gD = new LinkedList<>();
		Deque<Integer> gS = new LinkedList<>();
		tokens = new StringTokenizer(input.readLine());
		N = Integer.parseInt(tokens.nextToken());
		M = Integer.parseInt(tokens.nextToken());
		
		for(int n=0; n<N; n++) {
			tokens = new StringTokenizer(input.readLine());
			int d = Integer.parseInt(tokens.nextToken());
			int s = Integer.parseInt(tokens.nextToken());
			dodo.offerFirst(d);
			suyun.offerFirst(s);
		}
		System.out.println(getWinner(dodo,suyun,gD,gS,M));
	}

	private static String getWinner(Deque<Integer> dodo, Deque<Integer> suyun, Deque<Integer> gD, Deque<Integer> gS, int M) {
		while(M>0) {
			// 1. 도도 턴
			if(!dodo.isEmpty()) {
				gD.offerFirst(dodo.pollFirst());
				M--;
				if(dodo.isEmpty()) {
					return "su";
				}
			}else { // 도도 패 다 털렸네?
				return "su";
			}
			
			// 2. 종 칠지 확인
			if(!gD.isEmpty() && !gS.isEmpty() && gD.peek() + gS.peek() == 5) { // 수연이가 종을 치는 경우
				while(!gD.isEmpty()) {
					suyun.offerLast(gD.pollLast());
				}
				while(!gS.isEmpty()) {
					suyun.offerLast(gS.pollLast());
				}
			}else if((!gD.isEmpty() && gD.peek() == 5) || (!gS.isEmpty() && gS.peek() == 5)) { // 도도가 종을 치는 경우
				while(!gS.isEmpty()) {
					dodo.offerLast(gS.pollLast());
				}
				while(!gD.isEmpty()) {
					dodo.offerLast(gD.pollLast());
				}
			}
			if(M<=0) {
				break;
			}
			// 3. 수연 턴
			if(!suyun.isEmpty()) {
				M--;
				gS.offerFirst(suyun.pollFirst());
				if(suyun.isEmpty()) {
					return "do";
				}
			}else { // 수연이 패 다 털렸네?
				return "do";
			}
			
			// 4. 종 칠지 확인
			if(!gD.isEmpty() && !gS.isEmpty() && gD.peek() + gS.peek() == 5) { // 수연이가 종을 치는 경우
				while(!gD.isEmpty()) {
					suyun.offerLast(gD.pollLast());
				}
				while(!gS.isEmpty()) {
					suyun.offerLast(gS.pollLast());
				}
			}else if((!gD.isEmpty() && gD.peek() == 5) || (!gS.isEmpty() && gS.peek() == 5)) { // 도도가 종을 치는 경우
				while(!gS.isEmpty()) {
					dodo.offerLast(gS.pollLast());
				}
				while(!gD.isEmpty()) {
					dodo.offerLast(gD.pollLast());
				}
			}
		}
		if(dodo.size() > suyun.size()) {
			return "do";
		}else if(dodo.size() == suyun.size()) {
			return "dosu";
		}else {
			return "su";
		}
	}

	static String src = 
			"3 4\r\n" + 
			"1 2\r\n" + 
			"2 2\r\n" + 
			"1 1";
}

 

후기

 

 사람들이 적게 푼 문제는 그럴만한 이유가 있다. 정말 설명이 모호하며 내가 코딩을 하는지 국어공부를 하는지 모르겠다.

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/03   »
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
글 보관함