P1911 L國的戰(zhàn)斗之排兵布陣

1、思路

①當(dāng)n為1時(shí),很簡單直接輸出;

②當(dāng)n為2時(shí),無非下邊四種情況

其他情況可以通過旋轉(zhuǎn)得到。而上圖黑色框與n=1時(shí)的情況等價(jià)。

③當(dāng)n為3時(shí),

2、代碼

#include<iostream>
using namespace std;
static int c = -1;
void solve(int **a, int temp1, int special, int x1, int y1, int x, int y){//注:輸入指揮營位置下標(biāo)從0開始
    if(temp1 == 2){
        a[x1][y1] = c;
        a[x1+1][y1] = c;
        a[x1][y1+1] = c;
        a[x1+1][y1+1] = c;
        a[x][y] = special;
        --c;
        return;
    }else if(temp1 == 4){
        if(x < x1 + 2){
            if(y < y1 + 2){
                solve(a, 2, special, x1, y1, x, y);
                a[x1][y1 + 2] = a[x1][y1 + 3] = a[x1 + 1][y1 + 3] = c;
                a[x1 + 1][y1 + 2] = a[x1 + 2][y1 + 1] = a[x1 + 2][y1 + 2] = c - 1;
                a[x1 + 2][y1] = a[x1 + 3][y1] = a[x1 + 3][y1 + 1] = c - 2;
                a[x1 + 3][y1 + 2] = a[x1 + 2][y1 + 3] = a[x1 + 3][y1 + 3] = c - 3;
            }else{
                solve(a, 2, special, x1, y1 + 2, x, y);
                a[x1][y1] = a[x1][y1 + 1] = a[x1 + 1][y1] = c;
                a[x1 + 1][y1 + 1] = a[x1 + 2][y1 + 1] = a[x1 + 2][y1 + 2] = c - 1;
                a[x1 + 2][y1] = a[x1 + 3][y1] = a[x1 + 3][y1 + 1] = c - 2;
                a[x1 + 3][y1 + 2] = a[x1 + 2][y1 + 3] = a[x1 + 3][y1 + 3] = c - 3;
            }
        }else{
            if(y < y1 + 2){
                solve(a, 2, special, x1 + 2, y1, x, y);
                a[x1][y1] = a[x1][y1 + 1] = a[x1 + 1][y1] = c;
                a[x1][y1 + 2] = a[x1][y1 + 3] = a[x1 + 1][y1 + 3] = c - 1;
                a[x1 + 1][y1 + 1] = a[x1 + 1][y1 + 2] = a[x1 + 2][y1 + 2] = c - 2;
                a[x1 + 3][y1 + 2] = a[x1 + 2][y1 + 3] = a[x1 + 3][y1 + 3] = c - 3;
            }else{
                solve(a, 2, special, x1 + 2, y1 + 2, x, y);
                a[x1][y1] = a[x1][y1 + 1] = a[x1 + 1][y1] = c;
                a[x1][y1 + 2] = a[x1][y1 + 3] = a[x1 + 1][y1 + 3] = c - 1;
                a[x1 + 1][y1 + 1] = a[x1 + 1][y1 + 2] = a[x1 + 2][y1 + 1] = c - 2;
                a[x1 + 2][y1] = a[x1 + 3][y1] = a[x1 + 3][y1 + 1] = c - 3;
            }
        }
        c -= 4;
        return;
    }else{
        int temp2 = temp1 / 2, temp3 = c;
        --c;
        if(x < x1 + temp2){
            if(y < y1 + temp2){
                solve(a, temp2, temp3, x1 + temp2, y1 + temp2, x1 + temp2, y1 + temp2);
                solve(a, temp2, temp3, x1, y1 + temp2, x1 + temp2 - 1, y1 + temp2);
                solve(a, temp2, temp3, x1 + temp2, y1, x1 + temp2, y1 + temp2 - 1);
                solve(a, temp2, special, x1, y1, x, y);
            }else{
                solve(a, temp2, temp3, x1, y1, x1 + temp2 - 1, y1 + temp2 - 1);
                solve(a, temp2, temp3, x1 + temp2, y1, x1 + temp2, y1 + temp2 - 1);
                solve(a, temp2, temp3, x1 + temp2, y1 + temp2, x1 + temp2, y1 + temp2);
                solve(a, temp2, special, x1, y1 + temp2, x, y);
            }
        }else{
            if(y < y1 + temp2){
                solve(a, temp2, temp3, x1, y1, x1 + temp2 - 1, y1 + temp2 - 1);
                solve(a, temp2, temp3, x1, y1 + temp2, x1 + temp2 - 1, y1 + temp2);
                solve(a, temp2, temp3, x1 + temp2, y1 + temp2, x1 + temp2, y1 + temp2);
                solve(a, temp2, special, x1 + temp2, y1, x, y);
            }else{
                solve(a, temp2, temp3, x1, y1, x1 + temp2 - 1, y1 + temp2 - 1);
                solve(a, temp2, temp3, x1, y1 + temp2, x1 + temp2 - 1, y1 + temp2);
                solve(a, temp2, temp3, x1 + temp2, y1, x1 + temp2, y1 + temp2 - 1);
                solve(a, temp2, special, x1 + temp2, y1 + temp2, x, y);
            }
        }
    }
}
int main(){
    int n, x, y, i, j, temp1 = 2, count = 1;
    cin>>n>>x>>y;

    while(--n > 0) temp1 = temp1 << 1;
    
    int **a = new int *[temp1];
    int **mask = new int *[temp1];
    for(i = 0; i < temp1; ++i){
        a[i] = new int [temp1];
        mask[i] = new int [temp1]();//全部初始化為0
    }
    mask[x - 1][y - 1] = 1;
    
    solve(a, temp1, 0, 0, 0, x - 1, y - 1);

    for(i = 0; i < temp1; ++i){//重新排序并輸出
        for(j = 0; j < temp1; ++j){
            if((i == x - 1 && j == y - 1) || mask[i][j] != 0){
                cout<<a[i][j]<<" ";
                continue;
            }
            if(i + 1 < temp1 && mask[i + 1][j] == 0 && a[i + 1][j] == a[i][j]){
                if(j - 1 >= 0 && mask[i + 1][j - 1] == 0 && a[i + 1][j - 1] == a[i][j]){
                    a[i + 1][j] = a[i][j] = a[i + 1][j - 1] = count;
                    mask[i + 1][j] = mask[i][j] = mask[i + 1][j - 1] = 1;
                }else if(mask[i + 1][j + 1] == 0 && a[i + 1][j + 1] == a[i][j]){
                    a[i + 1][j] = a[i][j] = a[i + 1][j + 1] = count;
                    mask[i + 1][j] = mask[i][j] = mask[i + 1][j + 1] = 1;
                }else{
                    a[i + 1][j] = a[i][j] = a[i][j + 1] = count;
                    mask[i + 1][j] = mask[i][j] = mask[i][j + 1] = 1;
                }
            }else{
                a[i][j + 1] = a[i][j] = a[i + 1][j + 1] = count;
                mask[i][j + 1] = mask[i][j] = mask[i + 1][j + 1] = 1;
            }
            ++count;
            cout<<a[i][j]<<" ";
        }
        cout<<endl;
    }
    for(int i = 0; i < temp1; ++i)//釋放內(nèi)存空間
    {
        delete [] a[i]; 
        delete [] mask[i]; 
    }
    return 0;
}

3、可改進(jìn)

我這個(gè)解法相當(dāng)于把n=2當(dāng)作遞歸的邊界,其實(shí)n=2也可以劃分為四個(gè)n=1的情況,所以可以進(jìn)一步將n=1作為遞歸的邊界;可以不用靜態(tài)變量;

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容