Quiz
https://yukicoder.me/problems/247
Submit
https://yukicoder.me/submissions/336214
画像
- テストケース2
解法
- シミュレーションする
- 0の置かれている位置にあるべき数字を考える
- 画像で言えば「12」(3行目4列目なので)
- そのあるべき数字は上下左右にあるはず
- なければ解けない (各駒1度しか動かせないため)
- 交換する
- これで盤面は最適な状態に一歩近づいた
- 新しい空白から、同様の処理を繰り返す
- 動けなくなったら目的の配置になっているかチェックして終了
その他
- 解説Blogが少なかったので書いた
- 転倒数で求めるのは嘘解法という記述もあったのでシミュレーションで解いた
- とはいえ転倒数も面白い https://mathtrain.jp/8puzzle
- 15パズル
- あみだくじ
Code
int dx[4] = {-1, 0, 1, 0}; int dy[4] = {0, 1, 0, -1}; ll A[4][4]; // そこにあるべき数字 ll calc_number(ll i, ll j){ ll ret = 4 * i + j + 1; if(i==3 && j==3){ ret = 0; } return ret; } int main(){ cin.tie(0); ios::sync_with_stdio(false); // input FOR(i, 0, 4){ cin >> A[i][0]; cin >> A[i][1]; cin >> A[i][2]; cin >> A[i][3]; } ll empty_i; ll empty_j; FOR(i, 0, 4){ FOR(j, 0, 4){ if(A[i][j]==0){ empty_i = i; empty_j = j; } } } while(true){ bool found = false; // 上下左右を見る FOR(i, 0, 4){ // 空白部分にあるべき数字 ll number = calc_number(empty_i, empty_j); ll next_i = empty_i + dy[i]; ll next_j = empty_j + dx[i]; if(0<=next_i && next_i < 4 && 0<=next_j && next_j < 4 && A[next_i][next_j]==number){ swap(A[empty_i][empty_j], A[next_i][next_j]); empty_i = next_i; empty_j = next_j; found = true; } } // 4方向見ても見つからなかった if(!found){ goto HERE; } } HERE: // last check FOR(i, 0, 4){ FOR(j, 0, 4){ if(A[i][j]!=calc_number(i, j)){ p_no(); return 0; } } } p_yes(); return 0; }