第一道AK的深搜题
其实这道题也不是很难,想到深搜就很方便了,唯一一个难点是如何标记斜方向上不能放棋子的位置。
但其实也很简单,其实如果你学过初中的一次函数就知道如何解决了。以下是思路:
-
由于对于一个地图为n*m的矩形地图上的任意一点(x,y),斜方向可以看出一次函数。y=kx+b (k∈k+,b∈k+),所以y-x=(k-1)x+b。
-
但我们这个地图比较特殊,它是正方形的,所以斜方向的k=1,所以(k-1)=0。
- 所以我们可以发现(y-x)的值为一个定值d,且这个d在不同的斜方向值也不同,所以我们就可以用d值来标记斜方向。
(ps:这里有个小问题有些时候d会小于0,直接用数组无法标记,所以要对d小于0的方向的标记值加上一个较大的数,比如我加的就是14)
所以我们就的出了标记函数的写法:
void mark(int x,int y){
book_x[x]=1;
book1[x+y]=1;
book2[x-y+14]=1;
接下来用深搜就可以了#include <iostream> #include <cstdio> using namespace std; int book_x[15],book_y[15],book1[20],book2[30],n,ans[15]; void mark(int x,int y){ book_x[x]=1; book1[x+y]=1; book2[x-y+14]=1; } void replace(int x,int y){ book_x[x]=0; book1[x+y]=0; book2[x-y+14]=0; } int k=0,q=0,ans1=0; void dfs(int x,int deep){ if (deep==n+1){ if (k<=2){ k++; for (int i=0;i<n;i++){ printf("%d ",ans[i]); } printf("\n"); } ans1++;//答案数加一 return; } for (int i=1;i<=n;i++){ if (book1[i+deep]==0&&book_x[i]==0&&book2[i-deep+14]==0){ ans[q]=i;q++; mark(i,deep); dfs(i,deep+1); //以下为还原操作 replace(i,deep); q--; } } } int main(){ cin>>n; dfs(1,1); cout<<ans1; return 0; }