プログラマー[Kakao]ロックとキー(Java)


リンク


質問リンク

問題の説明


考古学者の「救命圏」は古代遺跡で秘密の扉を発見し、宝物や遺跡がたくさんあると推測した.ドアを開けてみると、ドアが特殊な形の鍵でロックされていて、ドアの前に紙があり、特殊な形の鍵でロックを解除する方法が書かれています.
ロックされたロックは、メッシュサイズが1 x 1のN x Nサイズの正方形メッシュであり、特殊な形状のキーはM x Mサイズの正方形メッシュである.
鍵には溝があり、鍵にも溝と突起があります.鍵は回転と移動が可能な構造で、鍵の回転部分が鍵の溝部分とぴったり合っていると鍵が開きます.ロック領域以外の鍵の溝と突起はロック解除に影響しないが、ロック領域内では鍵の突起とロックの溝が完全に一致し、鍵の突起とロックの突起にぶつかることができない必要がある.また、ロックのすべての溝を埋めなければなりません.そうすれば、ロックを解除できます.
パラメータにキーを表す2 D配列キーとロックを表す2 D配列ロックが与えられた場合、true(キーがロックを解除できる場合)とfalse(ロックを解除できない場合)を返すソルバを完了します.

せいげんじょうけん

  • 結合はMxM(3≦M≦20,Mは自然数)サイズの二次元配列である.
  • ロックは、NxN(3≦N≦20、Nは自然数)サイズの2次元配列である.
  • Mは常にNより小さい.
  • キーとlockの要素は0または1で構成されます.
  • 0は「主」部分、1は「回転」部分を表します.
  • I/O例



    I/O例説明


    写真が大きすぎてリンクで置き換える

    に答える


    拡張
  • ロック.(lock.length + key.length * 2)
  • は大きな配列ではないので、
  • に完全にナビゲートできることを認識してみましょう.
  • (0,0)から拡張されたロック(ソースコード上のag lock)対キーに、キー値
  • を加える.
    さらに
  • を加えるとag lockロック範囲の値が1
  • であることが確認される.
  • 2(回転付き)または0(ホームページ付き)がある場合は、
  • のみをナビゲートして追加したすべてのコンテンツを返します.
  • を4回と5回繰り返し、
  • を終了する.
    正直、これはただの配列問題で、私の考えは複雑すぎると思います.ううう
    でもどうしてロックなの.length + key.長さ*2新しい長さに拡張する必要があるかどうか分かりません…!
    私が考えている拡張範囲はlockです.length + key.長さ*2-2.このようにするといつも一つの場所を羽織ることができるからです.
    配列インデックスを決定する部分は、リンクにおいて役立つ.

    コード#コード#

    class Solution {
        public int[][] rotate(int[][] key) {
            int[][] resultArr = new int[key.length][key.length];
            for (int i = 0; i < resultArr.length; i++) {
                int tempIdx = resultArr.length - 1;
                for (int j = 0; j < resultArr.length; j++) {
                    resultArr[i][j] = key[tempIdx--][i];
                }
            }
            return resultArr;
        }
        public boolean locking(int[][] key, int[][] ag_lock, int x, int y) {
            for(int i = x; i < key.length + x; i++)
                for(int j = y; j < key.length + y; j++)
                    ag_lock[i][j] += key[i - x][j - y];
            for(int i = key.length - 1; i < ag_lock.length - (key.length + 1); i++) {
                for(int j = key.length - 1; j < ag_lock.length - (key.length + 1); j++) {
                    if(ag_lock[i][j] != 1){
                        for(int a = x; a < key.length + x; a++)
                            for(int b = y; b < key.length + y; b++)
                                ag_lock[a][b] -= key[a - x][b - y];                    
                        return false;
                    }
                }
            }
            return true;
        }
        public boolean solution(int[][] key, int[][] lock) {
            int[][] ag_lock = new int[lock.length + key.length * 2 - 2][lock.length + key.length * 2 - 2];
            for(int i = 0; i < lock.length ; i++)
                for(int j = 0; j < lock.length; j++)
                    ag_lock[i + key.length - 1][j + key.length - 1] = lock[i][j];
            for(int a = 1; a <= 4; a++) {
                for(int i = 0; i < ag_lock.length - (key.length + 1); i++) {
                    for(int j = 0; j < ag_lock.length - (key.length + 1); j++) {
                        if(locking(key,ag_lock,i,j))
                            return true;
                    }
                }
                key = rotate(key);
            }
            return false;
        }
    }