# Backtracking# Greedy# DFS# Array

c104 - 00167 - The Sultan's Successors

🔗 前往 ZeroJudge 原題

題目描述

題目描述了在一個 8x8 的棋盤上放置 8 個皇后,使得皇后彼此不攻擊,並找到放置方式使得皇后所在格子的數字總和最大。

解題思路

程式碼使用回溯法 (Backtracking) 產生所有可能的 8 皇后放置方案。vp 函數檢查在給定的位置放置皇后是否安全(不與其他皇后衝突)。lq 函數遞迴地嘗試在每一列放置皇后,如果找到一個有效的方案,則將其儲存在 ans 陣列中。主函數讀取棋盤上的數字,然後對於每個找到的 8 皇后放置方案,計算皇后所在格子的數字總和,並找到最大的總和。

複雜度分析

  • 時間複雜度: O(8^8 * 64)。產生所有 8 皇后解的複雜度約為 O(8^8),對於每個解,計算總和需要遍歷 8x8 的棋盤,因此是 O(64)。
  • 空間複雜度: O(8 * 8 * 92)。ans 陣列儲存所有可能的 8 皇后解,大小為 8x8x92。queen 陣列大小為 8x8。

程式碼

#include <iostream>
#include <iomanip>
using namespace std;
bool ans[8][8][92],queen[8][8];
int counter=0,maxn,t[8][8],k;
bool vp(int r , int c){ 
    for(int i=0;i<8;++i){ 
        if(queen[i][c]&&i!=r) 
            return 0; 
        else if(queen[r][i]&&i!=c) 
            return 0; 
        else if(r+i<8&&c+i<8&&queen[r+i][c+i]) 
            return 0; 
        else if(r+i<8&&c-i>=0&&queen[r+i][c-i]) 
            return 0; 
        else if(r-i>=0&&c+i<8&&queen[r-i][c+i]) 
            return 0; 
        else if(r-i>=0&&c-i>=0&&queen[r-i][c-i]) 
            return 0; 
    } 
    return 1; 
} 
void lq(int col){ 
    for(int j=0;j<8;++j){ 
        queen[col][j]=vp(col,j); 
        if(col==7&&queen[col][j]){ 
        	for(int ii=0;ii<8;++ii)
        		for(int jj=0;jj<8;++jj)
        			ans[ii][jj][counter]=queen[ii][jj];
            ++counter; 
            queen[col][j]=0; 
            break; 
        } 
        else if(queen[col][j]){ 
            lq(col+1); 
            queen[col][j]=0; 
        } 
    } 
} 
int main(){
	cin.tie(0); ios::sync_with_stdio(false);
	lq(0);
	cin >> k;
	while(k--){
		for(int i=0;i<8;++i)
			for(int j=0;j<8;++j)
				cin >> t[i][j];
		maxn=0;
		for(int cc=0;cc<92;++cc){
			int ansc=0;
			for(int i=0;i<8;++i)
				for(int j=0;j<8;++j)
					if(ans[i][j][cc])
						ansc+=t[i][j];
			if(ansc>maxn)
				maxn=ansc;
		}
		cout << setw(5) << maxn << "\n";
	}
}

Discussion