题目:
诸侯安置
【问题描述】
很久以前,有一个强大的帝国,它的国土成正方形状,如图1 所示
这个国家有若干诸侯。由于这些诸侯都曾立下赫赫战功,国王准备给他们每人一块封地
(正方形中的一格)。但是,这些诸侯又非常好战,当两个诸侯位于同一行或同一列时,他们
就会开战。如下图2 为n=3 时的国土,阴影部分表示诸侯所处的位置。前两幅图中的诸侯可
以互相攻击,第三幅则不可以。
国王自然不愿意看到他的诸侯们互相开战,致使国家动荡不安。因此,他希望通过
合理的安排诸侯所处的位置,使他们两两之同都不能攻击。
现在,给出正方形的边长n,以及需要封地的诸侯数量k,要求你求出所有可能的安置
方案数。(n≤100,k≤2n2-2n+1)
由于方案数可能很多,你只需要输出方案数除以504 的余数即可。
【输入】
仅一行,两个整数n 和k,中阍用一空格隔开。
【输出】
一个整数,表示方案数除以504 的余数。
【样例】
empire.in empire.out
2 2 4
#include<iostream>
#include<cstdio>
#include<math.h>
using namespace std;
int n,m,ans = 0;
int a[105];
void init(){
scanf("%d%d",&n,&m);
}
void dfs(int p,int now){
if(now == m){
ans = (ans+1)%504;//当now到达指定的个数时返回,并将答案加1mod504;
return ;
}
if(p == n*2)return;//当行到n*2时返回
dfs(p+1,now);//先递归到最后一层,在返回是进行搜索,方便计算列的区间
for(int i = 1+abs(n-p);i <= 2*n-1-abs(n-p); i++){//这样可以得到没一层的列的区间
int j;
for(j = 1;j < p;j++)if(a[j] == i)break;//判断在这一列上是否有诸侯
if(j == p){
a[p] = i;dfs(p+1,now+1);//记录坐标并到下一层
}
}
}
int main(){
freopen("Empire.in","r",stdin);
freopen("Empire.out","w",stdout);
init();
dfs(1,0);
printf("%d",ans);
}