思想:存三个数组记录记录走的过程,运用回溯不符合或row==n+1就跳出当前层,直到找完;递归时的路径都在保存着,当连续跳出到第一次进入的dfs且i=n时就全部跳出dfs函数了;
1 #include<stdio.h> 2 #include<string.h> 3 int n,sum; 4 int visit[3][100]; 5 int dp[11]; 6 void dfs(int row){int i; 7 if(row==n+1){ 8 sum++;return; 9 }//如果行等于要求找的行数,跳出这一层进行下一次查找 10 for(i=1;i<=n;i++){//一定要注意i为当前列数,变化的visit是一维数组,将行数转化为列数相当于将面化为线, 11 //分↑ 这三个数组,主要因为i是从小到大的,存一个数组会造成影响 12 if(visit[0][i]==0 && visit[1][i+row]==0 && visit[2][row-i+n]==0){/*i代表当前列数; 13 visit【i】代表当前这一列是否放皇后; visit[i+row]为是否放元素*/ 14 visit[0][i] = visit[1][i+row] = visit[2][row-i+n] = 1;//i代表列数,每次从1到n 15 dfs(row+1); 16 visit[0][i]=visit[1][i+row]=visit[2][row-i+n]=0;//回溯,当函数跳出当前层时,证明成功了,或不符合,然后回溯,使上一层走的不算;进行下一次查找; 17 }//如果if没执行证明不符合i++进行行中下一次查找; 18 } 19 return;//如果不符合跳出这一层; 20 } 21 int main(){int N; 22 for(n=1;n<=10;n++){sum=0; 23 memset(visit,0,sizeof(visit)); 24 dfs(1); 25 dp[n]=sum;//打表主要怕超时; 26 } 27 while(~scanf("%d",&N),N){ 28 printf("%d\n",dp[N]); 29 } 30 return 0; 31 }
推荐个帖子:http://topic.csdn.net/t/20060424/13/4709025.html
还有的大神用的位运算,写的;
n皇后问题将递归与回溯用到了极致。。。
时间: 2024-10-29 19:10:49