[ 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 }