新しいゲーム2(17837)
37302 ワード
1.質問
質問リンク
説明:
ヒョンは周囲を見ながら碁盤とマレーで新しいゲームを作ることにした.新しいゲームサイズはN×Nチェス盤で行い、使用する馬の個数はK個です.馬は原版で、1匹はすぐに別の馬を置くことができます.チェス盤の各コマは白、赤、青の1つに塗られている.
ゲームは碁盤にK頭馬を乗せてから始まります.馬は1番からK番まで番号があり、移動方向も予め決まっています.移動方向は、上、下、左、右の4つのいずれかです.
一回のターンは1番馬からK番馬の順に移動します.1頭の馬が移動すると、上の馬も一緒に移動します.馬の移動方向の欄によって、馬の移動は以下のように異なります.回転中に4つ以上の馬を積んだ瞬間、ゲームは終了.
第1ラウンドは以下のように行われる.
第2ラウンドは以下のように行われる.
碁盤の大きさ,馬の位置,移動方向ともにタイミングを与え,ゲーム終了時のラウンド番号を求める.
入力
1行目は碁盤サイズN,馬の個数Kを与える.2行目からN行はチェス盤の情報を与える.チェスボードの情報は整数で構成され、各整数はセルの色を表します.0は白、1は赤、2は青です.
次のK行では、馬の情報は1番馬から順に与えられます.馬の情報は、行、列の番号、移動方向の3つの整数で構成されています.行と列の番号は1から、移動方向は4以下、1から順に→、←、↑、↓です.
同じ欄に馬が2つ以上ある場合は入力できません.
しゅつりょく
ゲーム終了時のラウンド番号を出力します.この値が1000より大きい場合、またはゲームが絶対に終了しない場合は、-1を出力します.
2.解答
2-1. 条件
2-2. に答える
実装中のシミュレーション問題.
条件が多いだけで、難点はありませんが、ちょっと面倒です.
やっぱり誰もが計画を立てて解決しよう
計画1-回路基板をスタックアレイとして宣言します.
int [] my = {0, 0, -1, 1};
int [] mx = {1, -1, 0, 0};
int [] transDir = {1, 0, 3, 2};
int[][] horses = new int[K][3]; // 말의 정보를 담을 배열
Stack<Integer>[][] stackBoard = new Stack[N][N]; // 말들을 담을 스택 보드판
Stack<Integer> white = new Stack<>(); // 흰 칸으로 이동할 때 쓰이는 임시 스택
board = new int[N][N]; // 보드판
それ以外に必要な変数も発表した.現実世界の複雑な問題をデータ化してコンピュータが理解できるようにすることが重要である.
重要なアイデアの1つは、宣言ボードがスタックされていることです.
これは、赤いセルに移動する際に、スタックに
pop
万を供給すれば、問題の要求通りに実施できることを意味します.計画2-問題の要求に従ってゲームを行う.
この部分は純実現なので特に説明はありません.
完全なコードを確認します.
3.完全なコード
import java.util.Stack;
import java.util.StringTokenizer;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
public class Main {
static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
static BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
static int N, K;
static int[][] board;
// 파랑칸 여부 (좌표 밖이거나, 2일 때)
static boolean isBlue(int y, int x) {
return y < 0 || y >= N || x < 0 || x >= N || board[y][x] == 2;
}
public static void main(String[] args) throws Exception {
StringTokenizer stk = new StringTokenizer(br.readLine());
N = Integer.parseInt(stk.nextToken());
K = Integer.parseInt(stk.nextToken());
int [] my = {0, 0, -1, 1};
int [] mx = {1, -1, 0, 0};
int [] transDir = {1, 0, 3, 2};
int[][] horses = new int[K][3]; // 말의 정보를 담을 배열
Stack<Integer>[][] stackBoard = new Stack[N][N]; // 말들을 담을 스택 보드판
Stack<Integer> white = new Stack<>(); // 흰 칸으로 이동할 때 쓰이는 임시 스택
board = new int[N][N]; // 보드판
for (int i = 0; i < N; i++) {
stk = new StringTokenizer(br.readLine());
for (int j = 0; j < N; j++) {
stackBoard[i][j] = new Stack<>();
board[i][j] = Integer.parseInt(stk.nextToken());
}
}
for (int i = 0; i < K; i++) {
stk = new StringTokenizer(br.readLine());
int y = Integer.parseInt(stk.nextToken()) - 1;
int x = Integer.parseInt(stk.nextToken()) - 1;
int dir = Integer.parseInt(stk.nextToken()) - 1;
horses[i][0] = y;
horses[i][1] = x;
horses[i][2] = dir;
stackBoard[y][x].add(i);
}
int ans = -1;
int loop = 0;
a: while (true) {
loop++;
// 턴 돌리기
for (int i = 0; i < K; i++) {
// 현재 말의 정보를 가져온다
int[] horse = horses[i];
int y = horse[0];
int x = horse[1];
int dir = horse[2];
// 이동하려는 다음 칸
int ny = y + my[dir];
int nx = x + mx[dir];
// 파랑칸일 때
if (isBlue(ny, nx)) {
// 좌표를 반대로 바꿔준다
ny = y - my[dir];
nx = x - mx[dir];
horse[2] = transDir[dir];
// 반대 방향도 파랑칸일 때
if (isBlue(ny, nx)) continue;
}
switch (board[ny][nx]) {
case 0: // 흰색
while (!stackBoard[y][x].isEmpty()) {
int piece = stackBoard[y][x].pop();
white.add(piece);
if (piece == i) break; // 현재 이동하는 말일 때 탈출
}
while (!white.isEmpty()) {
int piece = white.pop();
// 이동하는 말들의 좌표 갱신
int[] info = horses[piece];
info[0] = ny;
info[1] = nx;
stackBoard[ny][nx].add(piece);
}
break;
case 1: // 빨간색
while (!stackBoard[y][x].isEmpty()) {
int piece = stackBoard[y][x].pop();
// 이동하는 말들의 좌표 갱신
int[] info = horses[piece];
info[0] = ny;
info[1] = nx;
stackBoard[ny][nx].add(piece);
if (piece == i) break; // 현재 이동하는 말일 때 탈출
}
break;
}
// 이동 후 말 4개 이상 모였다면 게임 끝
if (stackBoard[ny][nx].size() >= 4) {
ans = loop;
break a;
}
if (loop > 1000) break a;
}
}
bw.write(ans + "");
bw.close();
}
}
Reference
この問題について(新しいゲーム2(17837)), 我々は、より多くの情報をここで見つけました https://velog.io/@front/백준-새로운-게임-2-17837テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol