#include<string>#include<cstdio>#include<iostream>#include<algorithm>usingnamespace std;//由於每次掃描檢查次數太多,導致超時int N, pos;int s[20][20];bool vis[20][20];int res[100010][20];boolin(int x,int y){return x >=1&& x <= N && y >=1&& y <= N;}//檢查當前行和當前列有無佔用以及所有對角線intcheck(int a,int b){if(s[a][b])return1;//行和列for(int i =1; i <= N; i++)if(s[a][i])return1;for(int i =1; i <= N; i++)if(s[i][b])return1;//對角線int x = a, y = b;for(int i =1; i <= N; i++){
x +=1, y +=1;if(!in(x, y))break;if(s[x][y])return1;}
x = a, y = b;for(int i =1; i <= N; i++){
x -=1, y -=1;if(!in(x, y))break;if(s[x][y])return1;}
x = a, y = b;for(int i =1; i <= N; i++){
x -=1, y +=1;if(!in(x, y))break;if(s[x][y])return1;}
x = a, y = b;for(int i =1; i <= N; i++){
x +=1, y -=1;if(!in(x, y))break;if(s[x][y])return1;}return0;}voiddfs(int a){if(a == N +1)//N = 3{for(int i =1; i <= N; i++)for(int j =1; j <= N; j++)if(s[i][j]){res[pos][i]= j;break;}
pos ++;return;}//掃描當前行的列for(int i =1; i <= N; i++){if(!check(a, i)){
s[a][i]=1;dfs(a +1);
s[a][i]=0;}}}voidprint(){for(int i =0; i <3; i++){for(int j =1; j <= N; j++)
cout << res[i][j]<<" ";
cout << endl;}
cout << pos << endl;}intmain(){
cin >> N;dfs(1);print();return0;}
參考代碼2.0: 關於標記對角線的方法,i + j 和 i - j + N 。效果如圖,即同一對角線數字都是一樣的;同樣,這樣可以減少循環查找所需要的的時間。
#include<string>#include<cstdio>#include<ctime>#include<iostream>#include<algorithm>usingnamespace std;int N, pos;int s[20][20], f[100], b[100], c[100], d[100];bool vis[20][20];int res[100010][20];voiddfs(int a){if(a == N +1)//N = 3{for(int i =1; i <= N; i++)for(int j =1; j <= N; j++)if(s[i][j]){res[pos][i]= j;break;}
pos ++;return;}//掃描當前行的列for(int i =1; i <= N; i++){if(!b[i]&&!c[a + i]&&!d[a - i + N]){
s[a][i]=1;
b[i]=1; c[a + i]=1;
d[a - i + N]=1;dfs(a +1);
s[a][i]=0;
b[i]=0; c[a + i]=0;
d[a - i + N]=0;}}}voidprint(){for(int i =0; i <3; i++){for(int j =1; j <= N; j++)
cout << res[i][j]<<" ";
cout << endl;}
cout << pos << endl;}intmain(){
cin >> N;dfs(1);print();return0;}