检查一个如下的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个解。最后一行是解的总个数。
Input
输入包含多组测试数据,每组数据包含一个数字N (6 <= N <= 13) 表示棋盘是N x N大小的。
Output
对于每组测试数据,输出四行。
前三行为前三个解,每个解的两个数字之间用一个空格隔开。第四行只有一个数字,表示解的总数。
Sample Input
6
Sample Output
2 4 6 1 3 5
3 6 2 5 1 4
4 1 5 2 6 3
列号
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个解。最后一行是解的总个数。
Input
输入包含多组测试数据,每组数据包含一个数字N (6 <= N <= 13) 表示棋盘是N x N大小的。
Output
对于每组测试数据,输出四行。
前三行为前三个解,每个解的两个数字之间用一个空格隔开。第四行只有一个数字,表示解的总数。
Sample Input
6
Sample Output
2 4 6 1 3 5
3 6 2 5 1 4
4 1 5 2 6 3
4
第一种,没有优化的直接超时,循环每一行,放一个皇后,再来个循环,判断是否和前面的皇后同列或同对角线。
#include<stdio.h>
int tot,n,row[14],col,time;
void Search(int col)
{
int i,j;
if(col==n)
{
if(time++<3)
{
for(i=0; i<n-1; i++)
printf("%d ",row[i]+1);
printf("%d\n",row[n-1]+1);
}
tot++;
}
else
{
for(i=0; i<n; i++)
{
row[col]=i;//把第col行的皇后放在第i列
int flag=1;
for(j=0; j<col; j++)
if(row[col]==row[j]||col+row[col]==j+row[j]||col-row[col]==j-row[j])
{
flag=0;
break;
}
if(flag)
Search(col+1);
}
}
}
int main()
{
while(scanf("%d",&n)!=EOF)
{
tot=0;
time=0;
Search(0);
printf("%d\n", tot);
}
return 0;
}
第二种 ,找规律,i,col+i,col-i+n为定值 。
#include<stdio.h>
int tot,n,row[14],col,time,judge[3][50];
void Search(int col)
{
int i,j;
if(col==n)
{
if(time++<3)
{
for(i=0; i<n-1; i++)
printf("%d ",row[i]+1);
printf("%d\n",row[n-1]+1);
}
tot++;
}
// else
// {
// for(i=0; i<n; i++)
// {
// row[col]=i;//把第col行的皇后放在第i列
// int flag=1;
// for(j=0; j<col; j++)
// if(row[col]==row[j]||col+row[col]==j+row[j]||col-row[col]==j-row[j])
// {
// flag=0;
// break;
// }
// if(flag)
// Search(col+1);
// }
else for(i = 0; i < n; i++)
{
if(!judge[0][i] && !judge[1][col+i] && !judge[2][col-i+n]) //规律,i,col+i,col-i+n为定值。 把已有皇后所在的列,对角线,副对角线都设为 1
{
row[col] = i;
judge[0][i] = judge[1][col+i] = judge[2][col-i+n] = 1;
Search(col+1);
judge[0][i] = judge[1][col+i] = judge[2][col-i+n] = 0;
}
}
}
int main()
{
while(scanf("%d",&n)!=EOF)
// n=13;
{
tot=0;
time=0;
Search(0);
printf("%d\n", tot);
}
return 0;
}