题目地址:点击打开链接
思路:经典回溯吧,就是数据得预处理,不然会超时
AC代码:
#include <iostream>
using namespace std;
int c[20];
int n,sum;
void backtrack(int m)
{
int i,j,ok;
if(m == n)
{
sum++;
return;
}
for(i=0; i<n; i++)
{
ok = 1;//OK得每次重新赋值
c[m] = i;
for(j=0; j<m; j++)
{
if(m-c[m] == j-c[j] || m+c[m] == j+c[j] || c[m] == c[j])//判断主对角线,副对角线,列是否重复
{
ok=0;
break;
}
}
if(ok)
backtrack(m+1);
}
}
int main()
{
int a[11];
for(n=1; n<=10; n++)
{
sum = 0;
backtrack(0);
a[n] = sum;
}
while(cin>>n &&n)
{
cout<<a[n]<<endl;
}
return 0;
}
import java.util.Scanner;
public class Main {
static int[] loc = new int[20];
static int n;
static int sum;
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
//保存能放的个数
int[] num = new int[12];
for(n=1; n<=10; n++) {
sum = 0;
backTrack(0);
num[n] = sum;
}
while((n = in.nextInt()) != 0) {
System.out.println(num[n]);
}
}
public static void backTrack(int row) {
if(row == n) {
sum++;
return;
}
for(int i=0; i<n; i++) {
//第row行的皇后方法第i列
loc[row] = i;
boolean ok = true;
for(int j=0; j<row; j++) {
//判断列,主对角线,副对角线是否有皇后,原因见<<算法竞赛入门经典>>
if(loc[j] == loc[row] || row-loc[row] == j-loc[j] || row+loc[row] == j+loc[j]) {
ok = false;
break;
}
}
if(ok)
backTrack(row+1);
}
}
}