TYVJ P1080 N皇后 Label:dfs PS:以前做的一道题,贴出来防忘
描述
检查一个如下的6 x 6的跳棋棋盘,有六个棋子被放置在棋盘上,使得每行、每列只有一个,每条对角线(包括两条主对角线的所有平行线)上至多有一个棋子。
上面的布局可以用序列2 4 6 1 3 5来描述,第i个数字表示在第i行的相应位置有一个棋子,如下:
行号 1 2 3 4 5 6
列号 2 4 6 1 3 5
这只是跳棋放置的一个解。请编一个程序找出所有跳棋放置的解。并把它们以上面的序列方法输出。解按字典顺序排列。请输出前3个解。最后一行是解的总个数。
特别注意: 对于更大的N(棋盘大小N x N)你的程序应当改进得更有效。不要事先计算出所有解然后只输出(或是找到一个关于它的公式),这是作弊。如果你坚持作弊,那么你登陆tyvj的帐号将被无警告删除
上面的布局可以用序列2 4 6 1 3 5来描述,第i个数字表示在第i行的相应位置有一个棋子,如下:
行号 1 2 3 4 5 6
列号 2 4 6 1 3 5
这只是跳棋放置的一个解。请编一个程序找出所有跳棋放置的解。并把它们以上面的序列方法输出。解按字典顺序排列。请输出前3个解。最后一行是解的总个数。
特别注意: 对于更大的N(棋盘大小N x N)你的程序应当改进得更有效。不要事先计算出所有解然后只输出(或是找到一个关于它的公式),这是作弊。如果你坚持作弊,那么你登陆tyvj的帐号将被无警告删除
输入格式
一个数字N (6 <= N <= 13) 表示棋盘是N x N大小的。
输出格式
前三行为前三个解,每个解的两个数字之间用一个空格隔开。第四行只有一个数字,表示解的总数。
测试样例1
输入
6
输出
2 4 6 1 3 5
3 6 2 5 1 4
4 1 5 2 6 3
4
备注
usaco
代码
#include<cmath> #include<cstdio> #include<cstdlib> #include<cstring> #include<iostream> #include<algorithm> using namespace std;//注意,N皇后 int a[15]; bool b[15],c[30],d[30]; int sum,k=3,N; void print(){ if(k>0){ for(int i=1;i<=N;i++){ cout<<a[i]<<' '; } cout<<endl; --k; } sum++; } void tryy(int t){ int j; for(j=1;j<=N;j++){ if(b[j]&&c[t+j-1]&&d[t-j+N]){ a[t]=j; b[j]=false; c[t+j-1]=false; d[t-j+N]=false; if(t==N) print(); else tryy(t+1); b[j]=true; c[t+j-1]=true; d[t-j+N]=true; } } } int main(){ memset(b,1,sizeof(b)); memset(c,1,sizeof(c)); memset(d,1,sizeof(d)); // freopen("01.txt","r",stdin); scanf("%d",&N); tryy(1); printf("%d\n",sum); return 0; }
假装不存在1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 int a[30],b[30],c[30],jilu[30],N,cnt; 7 void print(){ 8 if(cnt<3){ 9 for(int i=1;i<=N;i++){ 10 printf("%d ",jilu[i]); 11 } 12 puts(""); 13 } 14 ++cnt; 15 } 16 17 void search(int j){ 18 for(int i=1;i<=N;i++){ 19 if(a[i]==0&&b[i+j-1]==0&&c[i-j+14]==0){ 20 jilu[j]=i; 21 a[i]=1; 22 b[i+j-1]=1; 23 c[i-j+14]=1; 24 25 if(j==N) print(); 26 else search(j+1); 27 28 a[i]=0; 29 b[i+j-1]=0; 30 c[i-j+14]=0; 31 } 32 33 } 34 } 35 int main(){ 36 // freopen("01.txt","r",stdin); 37 scanf("%d",&N); 38 search(1); 39 printf("%d\n",cnt); 40 return 0; 41 }
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 3.0 许可协议。转载请注明出处!