こんにちは、私は小さな灰色の類人猿で、バグを書くことができるプログラマーです!
私のコラム「DailyBlueBridge」に注目してください。このコラムの主な機能は、近年のBlue Bridge Cup州の大会や決勝戦の本当の質問を共有し、アルゴリズムのアイデア、データ構造などを分析することです。その中に存在し、あなたが学ぶのを助けるコンテンツより多くの知識と技術に!
タイトル:ルービックキューブのステータス
二次ルービックキューブは、2層のみのルービックキューブで、8つの小さなピースのみで構成されています。
図pl.pngに示すように。
シャオミンはとてもやんちゃで、3色しか好きではないので、自宅で2次ルービックキューブを次のように塗り直しました。
フロント:オレンジ
右:緑
上:黄色
左:緑
下:オレンジ
戻る:黄色
そのようなルービックキューブが破壊された後、いくつの異なる状態があるかを計算してください。
ルービックキューブの全体的な回転後に2つの状態が同じである場合、すべての辺の色が同じである場合、それは同じ状態と見なされます。
州の数を表す整数を提出してください。冗長な内容や説明文は記入しないでください。
問題解決のアイデア:
この質問では、主に候補者の空間的思考と論理的想像力を調べます。解決策は、主に各魔法の立方体をシミュレートすることです。質問の魔法の立方体は8つの小さな立方体で構成され、各立方体には6つの面があります。文字列を使用してこの6つの面を分割します。が表現され、各面の回転過程がシミュレートされ、回転中に各面の変化が記録され、対応する文字列が記録され、文字シーケンスが同じであるため、異なる回転を取得できます。状態今。
回答のソースコード:
import java.util.HashSet; public class Year2017_Bt4 { static char[][] start = {"oybbgb".toCharArray(), "oygbbb".toCharArray(), "bygbby".toCharArray(), "bybbgy".toCharArray(), "obbogb".toCharArray(), "obgobb".toCharArray(), "bbgoby".toCharArray(), "bbbogy".toCharArray()}; static char[][][] q = new char[2000000][8][6]; static HashSet<String> all_state = new HashSet<String>(); static int front, tail; static String to_string(char[][] a) { String ans = ""; for (int i = 0; i < 8; ++i) { ans += new String(a[i]); } return ans; } private static void swap(char[] a, int i, int j) { char t = a[i]; a[i] = a[j]; a[j] = t; } private static void swap(char[][] a, int i, int j) { char[] t = a[i]; a[i] = a[j]; a[j] = t; } //上层的块的旋转,面的相对位置调换 static void ucell(char[] a) { swap(a, 0, 2); swap(a, 2, 5); swap(a, 5, 4); } //上层顺时针旋转 static void u(char[][] s) { ucell(s[0]); ucell(s[1]); ucell(s[2]); ucell(s[3]); // 块的相对位置调换 swap(s, 1, 0); swap(s, 2, 1); swap(s, 3, 2); } //右层旋转是面的位置变化 static void rcell(char[] a) { swap(a, 1, 0); swap(a, 0, 3); swap(a, 3, 5); } static void r(char[][] s)//魔方右层顺时针转 { rcell(s[1]); rcell(s[2]); rcell(s[6]); rcell(s[5]); // 块的位置变化 swap(s, 2, 1); swap(s, 5, 1); swap(s, 6, 5); } static void fcell(char[] a) { swap(a, 2, 1); swap(a, 1, 4); swap(a, 4, 3); } static void f(char[][] s)//前面一层 顺时针转 { fcell(s[0]); fcell(s[1]); fcell(s[4]); fcell(s[5]); swap(s, 1, 5); swap(s, 0, 1); swap(s, 4, 0); } static void uwhole(char[][] s)//整个魔方从顶部看 顺时针转 用于判重 { u(s);//上层旋转 // 下层旋转 ucell(s[4]); ucell(s[5]); ucell(s[6]); ucell(s[7]); // 完成自旋后,块的位置变动 swap(s, 5, 4); swap(s, 6, 5); swap(s, 7, 6); } static void fwhole(char[][] s)//整个魔方从前面看 顺时针转 用于判重 { f(s); fcell(s[2]); fcell(s[6]); fcell(s[7]); fcell(s[3]); swap(s, 2, 6); swap(s, 3, 2); swap(s, 7, 3); } static void rwhole(char[][] s)//整个魔方从右边看 顺时针转 用于判重 { r(s); rcell(s[0]); rcell(s[3]); rcell(s[4]); rcell(s[7]); swap(s, 3, 7); swap(s, 0, 3); swap(s, 4, 0); } static boolean try_insert(char[][] s) { char[][] k = new char[8][6]; memcpy(k, s); for (int i = 0; i < 4; i++) { fwhole(k); for (int j = 0; j < 4; j++) { uwhole(k); for (int q = 0; q < 4; q++) { rwhole(k); if (all_state.contains(to_string(k))) { return false; } } } } all_state.add(to_string(k)); return true; } private static void memcpy(char[][] k, char[][] s) { for (int i = 0; i < 8; i++) { for (int j = 0; j < 6; j++) { k[i][j] = s[i][j]; } } } static void solve() { front = 0; tail = 1; all_state.add(to_string(start)); memcpy(q[front], start);//填充q[0],相当于第一个状态入队列 while (front < tail) { /*将其所有变形,尝试加入set中*/ memcpy(q[tail], q[front]);//拷贝到tail u(q[tail]);//上层顺时针旋转 if (try_insert(q[tail])) { tail++;//扩展队列 } memcpy(q[tail], q[front]);//拷贝到tail r(q[tail]);//右层顺时针旋转 if (try_insert(q[tail])) { tail++;//扩展队列 } memcpy(q[tail], q[front]);//拷贝到tail f(q[tail]);//前顺时针旋转 if (try_insert(q[tail])) { tail++;//扩展队列 } front++;//弹出队首 // cout << front << " " << tail << endl; } System.out.println(front); } public static void main(String[] args) { solve(); } }
サンプル出力: