背景:第三次培训的题目。培训讲了dfs和bfs,这是dfs,递归+回溯。做了好久。
学习:
1.测试的时候有很多数据,然而其实只要10个结果,所以先用数组,把10个结果全部算出来,存着,到时候直接调用就可以了。即:打表,预处理。
2.其中在判断不能45度斜线的时候把棋盘看做图用下表来求斜率开始想的是如果斜率等于1或-1都不可以,但是这些都是整型变量如果真实相除结果等于1.2还是会等于1,包括用abs()函数都是整型。所以用了:(y-str[j])==(x-j)||(y-str[j])==(j-x) 这样就好了。
3.输出中途值来差错。
4,回溯的基本模式就是一个循环加递归。
5,str[n]的巧妙运用,n是行,对应的值为列。
#include<stdio.h> #include<string.h> int b[10]={0};/*存放0到10每个对应结果。*/ int str[11];/*数组下标表示行数,值表示列数。*/ int sum=0;/*计可行次数。*/ int t=0; int n=0; bool judge(int x,int y);/*判断这个位置(x行y列)是否可以安放棋子。*/ void once(int z); /*按行放棋子的函数,z表示棋盘大小。*/ bool judge(int x,int y) { for(int j=0;j<x;++j) { if(str[j]==y||(y-str[j])==(x-j)||(y-str[j])==(j-x)) return false; } return true; } void once(int z) { if(t>n) { ++sum; --t; /*for(int k=0;k<=n;++k) printf("%d",str[k]); printf("\n\n");*/ } else { for(int i=0;i<=z;++i) { if(judge(t,i)) { str[t]=i;/*保存满足条件的行列。*/ ++t; once(n); } } --t; } } int main(void) { int m; for(;n<10;++n ) { sum=0; memset(str,0,sizeof(str)); /*初始化。*/ t=0;/*定义初始行下标为0,表示第一行。*/ once(n); b[n]=sum; } while(scanf("%d",&m)&&m) printf("%d\n",b[m-1]); return 0; }