题意:八皇后问题的扩展。8*8棋盘上每个格子都有一个整数,要求8个皇后所在格子的数字之后最大
解法一,回溯:
用vis数组记录 列,主对角(y-x), 副对角(y+x) 访问情况
#include<cstdio> #include<cstring> #include<iostream> #include<string> #include<algorithm> using namespace std; int C[50], vis[3][50], tot = 0, n = 8, nc = 0; int board[8][8]; int max_score; void search(int cur) { nc++; if(cur==n) { tot++; int score=0; for(int i=0;i<8;i++) score+=board[i][C[i]]; max_score=max(max_score, score); } else for(int i=0;i<n;i++) { if(vis[0][i] || vis[1][i-cur+n] || vis[2][i+cur]) continue; C[cur]=i; vis[0][i]=vis[1][i-cur+n]=vis[2][i+cur]=1; search(cur+1); vis[0][i]=vis[1][i-cur+n]=vis[2][i+cur]=0; } } int main() { int k; scanf("%d", &k); while(k--) { for(int i=0;i<8;i++) for(int j=0;j<8;j++) { scanf("%d", &board[i][j]); } memset(vis, 0, sizeof(vis)); max_score=0; search(0); printf("%5d\n", max_score); } return 0; }
解法二, STL next_permutation 遍历所有列排列
#include<cstdio> #include<cstring> #include<iostream> #include<string> #include<algorithm> using namespace std; int v[8][8], P[8]; bool judge() { for(int i=0;i<8;i++) for(int j=0;j<i;j++) if(j-P[j]==i-P[i] || j+P[j]==i+P[i]) return false; return true; } int main() { int T; scanf("%d", &T); while(T--) { for(int i=0;i<8;i++) { P[i]=i; for(int j=0;j<8;j++) scanf("%d", &v[i][j]); } int ans=0; do { if(!judge()) continue; int score=0; for(int i=0;i<8;i++) score+=v[i][P[i]]; ans=max(ans, score); }while(next_permutation(P, P+8)); printf("%5d\n", ans); } return 0; }