[ CodeVS冲杯之路 ] P1295

  不充钱,你怎么AC?

  题目:http://codevs.cn/problem/1295/

 

  数据很小,直接DFS,加上剪枝

  剪枝其实就是判重,首先深度是行下标,这里自带不重复,枚举的列下标,用 f 记录每一列是否用过

  斜着的用下标相加减控制,如下图

  

  x 为横坐标,y 为纵坐标

  对于每根红线,x+y 相等

  对于每根蓝线,n-x-y 相等

  我们就用 g 表示一条红线是否用过,y 表示一条蓝线是否用过

 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<cstring>
 4 #include<cmath>
 5 #include<iostream>
 6 #include<algorithm>
 7 using namespace std;
 8 
 9 const int N=30;
10 int ans,n;
11 bool f[N],g[N],y[N];
12 void dfs(int x)
13 {
14   if (x>n)
15     {
16       ans++;
17       return;
18     }
19   int i;
20   for (i=1;i<=n;i++)
21     {
22       if (f[i]||g[x+i]||y[n-x+i]) continue;
23       f[i]=1;
24       g[x+i]=1;
25       y[n-x+i]=1;
26       dfs(x+1);
27       f[i]=0;
28       g[x+i]=0;
29       y[n-x+i]=0;
30     }
31 }
32 int main()
33 {
34   scanf("%d",&n);
35   dfs(1);
36   printf("%d",ans);
37   return 0;
38 }

 

posted @ 2016-09-22 21:22  Hadilo  阅读(180)  评论(0编辑  收藏  举报