UESTC 1851 Kings on a Chessboard

Kings on a Chessboard

Time Limit: 10000ms
Memory Limit: 65535KB
This problem will be judged on  UESTC. Original ID:  1851
64-bit integer IO format:  %lld      Java class name:  Main
Prev 
Submit  Status  Statistics  Discuss
  Next

UESTC 1851 Kings on a Chessboard_第1张图片You are given a chessboard of size x * y and k identical kings, and are asked to place all the kings on the board such that no two kings can attack each other. Two kings can attack each other if they are horizontally, vertically or diagonally adjacent.
Write a computer program that calculates the number of possible arrangements of the k kings on the given chessboard. Since the number of feasible arrangements may be large, reduce the number modulo 1,000,000,007.

Input

The first line of the input consists of a single integer T, the number of test cases. Each of the following T lines consists of three integers x; y and k,separated by one space.

 0 < T <= 50
 2 <= x; y <= 15
 1 <= k <= x*y

Output

For each test case, output the number of possibilities modulo 1,000,000,007.

Sample Input

4
8 8 1
7 7 16
7 7 7
3 7 15

Sample Output

64
1
2484382
0

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
const int mod=1000000007;
int n,m,k;
typedef long long ll;
ll dp[17][1<<11][250];
int nums,state[1600],man[1600],kth,cnt;
bool ok(int x)
{
    if(x&(x>>1))return 0;if(x&(x<<1))return 0;
    return 1;
}
bool ok1(int down,int up)
{
    down=state[down],up=state[up];
    if(down&up)return 0;
    if((down<<1)&up)return 0;if((down>>1)&up)return 0;
    return 1;
}
void get()
{
    cnt=0;memset(man,0,sizeof man);
    memset(state,0,sizeof state);
    for(int i=0;i<(1<<m);i++)
    {
        if(ok(i))
        {
            state[cnt]=i;
            int t=i;
            while(t)
            {
                if(t&1)man[cnt]++;
                t>>=1;
            }
            cnt++;
        }
    }
}
void update(ll &a,ll b)
{
    a=(a+b)%mod;
}
void solve()
{
    get();
    for(int i=0;i<cnt;i++)
        dp[1][i][man[i]]=1;
    for(int i=2;i<=n;i++)
    {
        for(int j=0;j<cnt;j++)
        {
            for(int k=0;k<cnt;k++)
            {
                if(!ok1(j,k))continue;
                for(int t=man[k];t<=kth;t++)
                {
                    if(t+man[j]<=kth)
                        update(dp[i][j][t+man[j]],dp[i-1][k][t]);
                }
            }
        }
    }
    ll ans=0;
    for(int j=0;j<cnt;j++)
        update(ans,dp[n][j][kth]);
    cout<<ans<<endl;
}
int main()
{
    int T;cin>>T;
    while(T--)
    {
        scanf("%d%d%d",&n,&m,&kth);
        memset(dp,0,sizeof dp);
        if(kth>(n+1)/2*(m+1)/2){puts("0");continue;}
        if(n<m)swap(n,m);
        solve();
    }
}


你可能感兴趣的:(UESTC 1851 Kings on a Chessboard)