結果

問題 No.217 魔方陣を作ろう
ユーザー codershifthcodershifth
提出日時 2016-01-26 00:16:23
言語 C++11
(gcc 11.4.0)
結果
AC  
実行時間 2 ms / 5,000 ms
コード長 3,761 bytes
コンパイル時間 1,934 ms
コンパイル使用メモリ 174,128 KB
実行使用メモリ 4,348 KB
最終ジャッジ日時 2023-10-21 15:01:10
合計ジャッジ時間 3,017 ms
ジャッジサーバーID
(参考情報)
judge14 / judge12
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 1 ms
4,348 KB
testcase_01 AC 2 ms
4,348 KB
testcase_02 AC 1 ms
4,348 KB
testcase_03 AC 2 ms
4,348 KB
testcase_04 AC 2 ms
4,348 KB
testcase_05 AC 2 ms
4,348 KB
testcase_06 AC 2 ms
4,348 KB
testcase_07 AC 1 ms
4,348 KB
testcase_08 AC 1 ms
4,348 KB
testcase_09 AC 1 ms
4,348 KB
testcase_10 AC 1 ms
4,348 KB
testcase_11 AC 2 ms
4,348 KB
testcase_12 AC 2 ms
4,348 KB
testcase_13 AC 1 ms
4,348 KB
testcase_14 AC 1 ms
4,348 KB
testcase_15 AC 1 ms
4,348 KB
testcase_16 AC 2 ms
4,348 KB
testcase_17 AC 2 ms
4,348 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

#include <bits/stdc++.h>

typedef long long ll;
typedef unsigned long long ull;

#define FOR(i,a,b) for(int (i)=(a);i<(b);i++)
#define REP(i,n) FOR(i,0,n)
#define RANGE(vec) (vec).begin(),(vec).end()

using namespace std;


class MakeMagicSquare
{
public:
    typedef vector<vector<int>> Mat;
    void report(const Mat &mat) {
        int n = mat.size();
        REP(i,n)
        {
            REP(j,n)
            {
                cout<<mat[i][j];
                if (j < n-1)
                    cout<<" ";
            }
            cout<<endl;
        }
    }
    Mat makeOddMS(int n) {
        Mat mat(n,vector<int>(n,0));
        int i,j;
        i = 0;
        j = n/2;
        for (int k = 1; k <= n*n; ++k)
        {
            mat[i][j] = k;

            int ii = i, jj = j;
            i = (i-1+n)%n;
            j = (j+1)%n;
            if ( mat[i][j] > 0)
            {
                i = (ii+1)%n;
                j = jj;
            }
        }
        return mat;
    }
    Mat make4xMS(int n) {
        Mat mat(n,vector<int>(n,0));
        auto tmp(mat);

        // 白黒ボードとして tmp を塗る
        // 4x4 ブロックに区切り対角線部のみぬる
        REP(dx,n/4)
        REP(dy,n/4)
        {   // 左上の座標を計算
            int x = 4*dx;
            int y = 4*dy;
            REP(i,4)
            {
                tmp[x+i][y+i] = 1;
                tmp[x+i][(4+y)-1-i] = 1;
            }
        }
        int x,y;
        x = y = 0;
        // 左上から右へブロックの対角線部のみ数字をおく
        for (int k = 1; k <= n*n; ++k)
        {
            if ( tmp[y][x] )
                mat[y][x] = k;
            ++x;
            if ( x == n )
            {
                ++y;
                x = 0;
            }
        }
        x = y = n-1;
        for (int k = 1; k <= n*n; ++k)
        {
            if ( !tmp[y][x] )
                mat[y][x] = k;
            --x;
            if ( x < 0 )
            {
                --y;
                x = n-1;
            }
        }
        return mat;
    }
    Mat LUX(int n) {
        int m = n/2;
        auto small = makeOddMS(m);

        REP(i,m)
        REP(j,m)
            small[i][j] = 4*(small[i][j]-1);

        vector<vector<char>> lux(m,vector<char>(m,'L'));
        REP(i,m)
            lux[m/2+1][i] = 'U';
        FOR(i,m/2+2,m)
        REP(j,m)
            lux[i][j] = 'X';
        swap(lux[m/2][m/2], lux[m/2+1][m/2]);

        Mat mat(n,vector<int>(n,0));
        const Mat L = {{4,1},
                       {2,3}};
        const Mat U = {{1,4},
                       {2,3}};
        const Mat X = {{1,4},
                       {3,2}};
        REP(i,n)
        REP(j,n)
        {
            int iy = i/2;
            int ix = j/2;
            int dy = i%2;
            int dx = j%2;

            switch ( lux[iy][ix] )
            {
            case 'L':
                mat[i][j] = L[dy][dx] + small[iy][ix];
                break;
            case 'U':
                mat[i][j] = U[dy][dx] + small[iy][ix];
                break;
            case 'X':
                mat[i][j] = X[dy][dx] + small[iy][ix];
                break;
            }
        }
        return mat;
    }
    void solve(void)
    {
        int n;
        cin>>n;

        int N = n*(n*n+1)/2;

        if (n % 2 == 1)
        {
            report(makeOddMS(n));
        }
        else if (n % 4 == 0)
        {
            report(make4xMS(n));
        }
        else if (n % 4 == 2)
        {
            report(LUX(n));
        }
    }
};

#if 1
int main(int argc, char *argv[])
{
        ios::sync_with_stdio(false);
        auto obj = new MakeMagicSquare();
        obj->solve();
        delete obj;
        return 0;
}
#endif
0