[白俊14499号]サイコロC++


[14499回サイコロ]
https://www.acmicpc.net/problem/14499
そんなに難しい問題ではないようです.多くの方法があるが,筆者はサイコロ展開図を表す2次元配列と地図を表す2次元配列を作成して解いた.

解答方法


1.


サイコロを左(上)に転がすことが右(下)に3回転がすことに等しいことから考えられる(このドメインも成立).

2.


コマンドに従ってスクロール方向を決定した後、該当する順序で変更した番号をQueueに入れ、変更した順序でQueueから抜いて再代入します(Queueとは限りません).
まず右と下にスクロールする関数を定義し、左と上はそれぞれ3回の逆スクロールを実行する関数として定義します.

3.


そうすると、上と下はいつもサイコロ[1]とサイコロ[3][1]で固定されています.mapや数字を与えるときは常にdice[3][1]、出力するときは常にdiceを出力する[1][1].
注意事項:問題の入力では,入力の順序は明らかにn,m,x,y,Kであるが,実際にはn,m,y,x,Kである.
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <vector>
#include <utility>  // pair
#include <tuple>
#include <stack>
#define ll long long
#define INF 1e9
using namespace std;

int n,m,x,y,K;
int map[20][20];
int dice[4][3];  // top face is dice[1][1], bottom face is dice[3][1] in the first place
int r,c;
int dr[] = {0,0,-1,1};
int dc[] = {1,-1,0,0};
int top, bottom;
queue<int> commands;

void rollDown() {
	queue<int> q;

	q.push(dice[3][1]);
	for(int i=0;i<3;++i) {
		q.push(dice[i][1]);
	}

	dice[0][1] = q.front();
	q.pop();
	for(int i=1;i<4;++i) {
		dice[i][1] = q.front();
		q.pop();
	}
}

void rollUp() {
	for(int i=0;i<3;++i) {
		rollDown();
	}
}

void rollRight() {
	queue<int> q;
	q.push(dice[3][1]);
	for(int i=0;i<3;++i) {
		q.push(dice[1][i]);
	}

	for(int i=0;i<3;++i) {
		int num = q.front();
		q.pop();

		dice[1][i] = num;
	}
	dice[3][1] = q.front();
	q.pop();
}

void rollLeft() {
	for(int i=0;i<3;++i) {
		rollRight();
	}
}

void sol() {
	while(!commands.empty()) {
		int type = commands.front();
		commands.pop();
		int nr, nc;
		nr = r + dr[type-1];
		nc = c + dc[type-1];

		if(nr < 0 || nr >= n || nc < 0 || nc >= m) {
			continue;
		}

		r = nr; c = nc;
		if(dr[type-1] > 0) {
			rollDown();
		} else if(dr[type-1] < 0) {
			rollUp();
		}

		if(dc[type-1] > 0) {
			rollRight();
		} else if(dc[type-1] < 0) {
			rollLeft();
		}


		if(map[r][c] == 0) {
			map[r][c] = dice[3][1];
		} else {
			dice[3][1] = map[r][c];
			map[r][c] = 0;
		}

		cout << dice[1][1] << '\n';
	}
}

int main(void) {
	ios_base :: sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
	cin >> n >> m >> y >> x >> K;
	r = y;
	c = x;
	top = 1; bottom = 3;

	for(int i=0;i<n;++i) {
		for(int j=0;j<m;++j) {
			cin >> map[i][j];
		}
	}
	for(int i=0;i<K;++i) {
		int k;
		cin >> k;
		commands.push(k);
	}

	sol();

	return 0;
}