题目描述
检查一个如下的6 x 6的跳棋棋盘,有六个棋子被放置在棋盘上,使得每行,每列,每条对角线(包括两条主对角线的所有对角线)上都至多有一个棋子。
列号
1 2 3 4 5 6
-------------------------
1 | | O | | | | |
-------------------------
2 | | | | O | | |
-------------------------
3 | | | | | | O |
-------------------------
4 | O | | | | | |
-------------------------
5 | | | O | | | |
-------------------------
6 | | | | | O | |
-------------------------
上面的布局可以用序列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)你的程序应当改进得更有效。不要事先计算出所有解然后只输出,这是作弊。如果你坚持作弊,那么你登陆USACO Training的帐号将被无警告删除
输入
一个数字N (6 <= N <= 13) 表示棋盘是N x N大小的
输出
前三行为前三个解,每个解的两个数字之间用一个空格隔开。第四行只有一个数字,表示解的总数。
样例输入
6
样例输出
2 4 6 1 3 5 3 6 2 5 1 4 4 1 5 2 6 3 4
题意描述:就是8皇后问题,输入一个数值n代表棋盘的大小n*n,在棋盘上放置n个棋子,要求满足;
1.每行只有一个棋子;
2.每列只有一个棋子;
3.没个斜对角线上只有一个棋子;
解题思路:按行排列就不用考虑每行会重复考虑斜对角线和列不重复就可以了;
斜对角判断代码:
if(c[cur]==c[j] || cur-c[cur]==j-c[j] || cur+c[cur]==j+c[j])
完整代码:注释掉的是打表过程(否者会超时)
#include<stdio.h>
int cur,c[20];
int a[20],tot;
int b[]={0,0,0,0,0,0,4,40,92,352,724,2680,14200,73712};
int find[8][50]={{2,4,6,1,3,5,3,6,2,5,1,4,4,1,5,2,6,3},
{1,3,5,7,2,4,6,1,4,7,3,6,2,5,1,5,2,6,3,7,4},
{1,5,8,6,3,7,2,4,1,6,8,3,7,4,2,5,1,7,4,6,8,2,5,3},
{1,3,6,8,2,4,9,7,5,1,3,7,2,8,5,9,4,6,1,3,8,6,9,2,5,7,4,},
{1,3,6,8,10,5,9,2,4,7,1,3,6,9,7,10,4,2,5,8,1,3,6,9,7,10,4,2,8,5},
{1,3,5,7,9,11,2,4,6,8,10,1,3,6,9,2,8,11,4,7,5,10,1,3,7,9,4,2,10,6,11,5,8},
{1,3,5,8,10,12,6,11,2,7,9,4,1,3,5,10,8,11,2,12,6,9,7,4,1,3,5,10,8,11,2,12,7,9,4,6},
{1,3,5,2,9,12,10,13,4,6,8,11,7,1,3,5,7,9,11,13,2,4,6,8,10,12,1,3,5,7,12,10,13,6,4,2,8,11,9},
};
//void search(int n,int cur)
//{
// int i,j;
// if(cur==n)
// {
// for(i=0;i<n;i++)
// printf("%d,",c[i]+1);
// tot++;
// if(tot>=2)
// return;
// }
// else
// for(i=0;i<n;i++)
// {
// int ok=1;
// c[cur]=i;
// for(j=0;j<cur;j++)
// if(c[cur]==c[j] || cur-c[cur]==j-c[j] || cur+c[cur]==j+c[j])
// {
// ok=0;
// break;
// }
// if(ok)
// {
// if(tot>2)
// return;
// search(n,cur+1);
// }
//
// }
// }
int main()
{
int i,j,k,m,n;
// for(i=6;i<=13;i++)
// {
// tot=0;
// search(i,0);
// printf("%d\n",b[i]);
//
// }
while(scanf("%d",&n)!=EOF)
{
for(i=1;i<=3*n;i++)
{
printf("%d ",find[n-6][i-1]);
if(i%n==0)
printf("\n");
}
printf("%d\n",b[n]);
}
return 0;
}