游客 Signup | Login
中文 | En

2486 - J

象 是国际象棋中的一种棋子,象的走法只可斜走,格数不限,但不可转向。
    白格的象只可以在白格出现,黑格的象只可以在黑格出现。
    现在给你一个n*n的棋盘,放置恰好k只象,且每只象不在其他象的攻击范围之内,输出方案数对(1e9+7)取余的值。

Input

多组数据,每组输入n,k (n<100,k<10000)

<br />

Output

输出方案数%1000000007。

Examples

Input

2 1
2 2
6 8

Output

4
4
12944

Hint

First sample: 22的棋盘上放置一枚象,有四种方案:
10  01  00  00
00  00  10  01
Second sample: 2
2的棋盘上放置两枚象,有如下四种方案:
11  10  01  00
00  10  01  11

Solution C++

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
typedef long long LL;
#define mod 1000000007
#define N 101
int b[N],w[N];
int n,k;
LL R_b[N][N*N],R_w[N][N*N];
void cal(int c[],LL R[][N*N]){
    memset(R,0,sizeof(R));
    for(int i=0;i<=n;i++) R[i][0]=1;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=c[i];j++)
            R[i][j]=(R[i-1][j]+R[i-1][j-1]*(c[i]-(j-1)))%mod;
}
int main(){
    //freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    while(scanf("%d%d",&n,&k)!=EOF){
        if(n==0 && k==0) break;
        memset(b,0,sizeof(b)),memset(w,0,sizeof(w));
        memset(R_w,0,sizeof(R_w)),memset(R_b,0,sizeof(R_b));
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
                if((i+j)&1) w[(i+j)>>1]++;
                else b[(i+j)>>1]++;
        sort(w+1,w+n),sort(b+1,b+n+1);
        cal(w,R_w),cal(b,R_b);
        LL ans=0;
        for(int i=0;i<=k;i++)
            ans=(ans+R_w[n-1][i]*R_b[n][k-i])%mod;
        printf("%lld\n",ans);
    }
    return 0;
}

Hint

First sample: 22的棋盘上放置一枚象,有四种方案:
10  01  00  00
00  00  10  01
Second sample: 2
2的棋盘上放置两枚象,有如下四种方案:
11  10  01  00
00  10  01  11

Time Limit 1 second
Memory Limit 128 MB
Discuss Stats
上一题 下一题