2n皇后 - 回溯
题目地址:http://www.51cpc.com/web/problem.php?id=1172
Summarize:
1. 递归回溯;
2. 先扫完一种皇后,再扫描另一种;
3. 循环输入;
4. 每列每种皇后必有一个,依次搜索;
附代码:
/* 2018-07-24 2n皇后 -回溯 每列必有一黑一白两个皇后,依次搜索; 将其中一种皇后放置完后,放置第二种皇后; */ #include<iostream> #include<cmath> using namespace std; #define LL long long const int N = 8+2; int n, vis[N][N]; LL ans=0; bool check(int x, int y, int queen) { if(vis[x][y] != 1) return false; if(x<0 || x>=n || y<0 || y>=n) return false; for(int i=0; i<n; i++) { if(vis[x][i] == queen || vis[i][y] == queen) return false; if(vis[x+i][y+i] == queen && x+i<n && y+i<n || vis[x-i][y-i] == queen && x>=i && y>=i || vis[x+i][y-i] == queen && y>=i && x+i<n || vis[x-i][y+i] == queen && x>=i && y+i<n) return false; } return true; } void bqueen(int x) //3 - black { if(x == n) { ans++; return; } for(int i=0; i<n; i++) { if(!check(x, i, 3)) continue; vis[x][i] = 3; bqueen(x+1); vis[x][i] = 1; } } void wqueen(int x) //2 - white { if(x == n) { bqueen(0); return; } for(int i=0; i<n; i++) { if(!check(x, i, 2)) continue; vis[x][i] = 2; wqueen(x+1); vis[x][i] = 1; } } int main() { ios::sync_with_stdio(false); while(cin>>n) { for(int i=0; i<n; i++) for(int j=0; j<n; j++) cin>>vis[i][j]; ans=0; if(n) wqueen(0); cout<<ans<<endl; } return 0; }