BOJ 1018:碁盤を塗り直す-C++


碁盤を塗り直す



コード#コード#

#include <iostream>
using namespace std;

int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);

    int N, M;
    cin >> N >> M;
    char origin[N][M];
    for(int i=0;i<N;i++)
        cin >> origin[i];

    int MIN=N*M;
    for(int a=0;a<=N-8;a++)
    {
        for(int b=0;b<=M-8;b++)
        {
            int ans[2] = {0,0};
            char board[2][8][8];
            for(int i=0;i<8;i++)
                for(int j=0;j<8;j++)
                {
                    board[0][i][j] = origin[i+a][j+b];
                    board[1][i][j] = origin[i+a][j+b];
                }
            for(int z=0;z<2;z++)
            {
                char prev;
                if(z == 0) prev='B';
                else prev='W';
                for(int i=0;i<8;i++)
                {
                    if(i != 0) prev=board[z][i-1][0];
                    for(int j=0;j<8;j++)
                    {
                        if(board[z][i][j] == prev){
                            ans[z]++;
                            if(prev == 'W') board[z][i][j] = 'B';
                            else board[z][i][j] = 'W';
                        }
                        if(prev == 'W') prev = 'B';  
                        else prev = 'W';
                    }
                }
            }
            MIN = min(MIN, min(ans[0], ans[1]));
        }
    }
    cout << MIN;
    return 0;
}
  • 論理
    1)origin[][]に盤全体を保存する
    2)全てforドアフレームでa=N-8 ~ b=M-8まで回転し、board[][]指定範囲にコピー!
    3)8 x 8チェス盤board[][]において左上隅が「W」のとき/「B」のとき最小変更回数を検索する
    4)min値更新
  • の要求に従って実施すれば、問題は解決する
  • .