問題の説明
シャオミンは近所の子供たちに小学校のオリンピックを教えているのですが、最近彼が話していたのは3次の幻の正方形という部分についてでした。3次の正方形とは、3*3の行列に1~9を繰り返し入れず、各行、列、対角線の和が同じになるようにすることです。3次立方体は9次立方体とも呼ばれ、小学校のオリンピックでは「2と4は肩、6と8は足、3は左、7は右、9は右、5は真ん中」という非常に有名なニーモニックがあり、このニーモニックによって9次立方体を非常に完璧に構築することができます。4 9 2 3 5 7 8 1 6
このように、 9つのマス目に対してイメージと回転の操作をいくつも行う ことで、3次のファントムキューブがすべて得られることは興味深い。さて、明は3次キューブの数字をいくつか消して、隣の家の子に渡して復元してもらいますが、解が1つしかないかどうかを判断できるようになってほしいのです。一方、あなたは明から同じ課題を与えられていますが、プログラムを書く必要があるという違いがあります。各テストデータは3*3の行列で、0の部分が明によって消去された部分を示します。100%のデータについて、与えられた行列が少なくとも1つの3次ファントム正方形の実現可能な集合を減少させることを満足しなさい。出力形式 実現可能な3次ファントム正方形集合が1つだけ削減できればそれを出力し、そうでなければ "Too Many" を出力。サンプル入力 0 7 2 0 5 0 0 3 0 サンプル出力 6 7 2 1 5 9 8 3 4 データサイズと規約 ピーク時メモリ消費量 < 256M CPU消費量 < 1000ms
感想:
まず、タイトルから、実は3次のファントム・キューブは、解が1つしかなく、他の解はすべて回転して得られるということがわかりますが、イメージでは、4通りしか回転できず、イメージでは、全部で8通りです。暴力的な解は終了です。しかし、どのように暴力的なそれを知るために観察を通じて、真ん中が5でなければならず、唯一の2つの数字は、あなたが唯一の3次のファントムスクエアを決定することができますので、インデックスの最初の2つの数字を取得するために、0と5を除外し、あなたは8つのケースを通過することができ、2つのインデックスの判断を通じて、限り、それが対応する位置にあるとして、両方の3次のファントムスクエアを見つけることに等しいです。
コードの実装:
public class Test4 {
public static void main(String[] args) {
method1("400950000");
}
//彼は3次ファントム正方形が存在するかどうかを確認する行列を入力し、さらに1つ以上
private static void method1(String matrix) {
long start = System.currentTimeMillis();
char[] chars = matrix.toCharArray();
int i = 0;
//5を除く2つのインデックスを保存する
int[] index = new int[2];
int j = 0;
//すべてのケースを保存する
ArrayList<String> arr = new ArrayList<>();
//文字配列を繰り返し、5に加えて、2つの価値のあるインデックスを取得する
for (; i < chars.length; i++) {
char a = chars[i];
if (a!= '0' && a!='5'){
if (j < 2){
index[j] = i;
j++;
}
}
//対応する位置が値であるかどうかを確認するために、各可能性を繰り返し実行する
arr.add("492357816");
arr.add("294753618");
arr.add("834159672");
arr.add("438951276");
arr.add("618753294");
arr.add("276951438");
arr.add("816357492");
arr.add("672159834");
}
//int型に保存する[]
System.out.println(Arrays.toString(index));
for (String s : arr) {
//文字の既知の配列を文字セットに変換する
char[] tar = s.toCharArray();
if (tar[index[0]] == chars[index[0]] && tar[index[1]] == chars[index[1]]){
System.out.println(s);
break;
}
}
long end = System.currentTimeMillis();
System.out.println(end-start+ " ミリ秒");
}
}