//    uva 11806 Cheerleaders
//
//    题目大意:
//
//        给你n * m的矩形格子,要求放k个相同的石子,使得矩形的第一行
//    第一列,最后一行,最后一列都必须有石子.
//
//    解题思路:
//
//        容斥原理,我们这样考虑,如果只是n * m放石子,那么最后的结果
//    就是C(n*m,k).我们设A为第一行不放石头的总数,B为最后一行不放石子
//    的总数,C为第一列不放石子的总数,D为最后一列不放石子的总数.则问题
//    转化为在全集S中,求不在A,B,C,D部分的解.则答案为S - | A | - | B |
//    - | C | - | D | + | A ^ B|......用一个二进制枚举状态,统计就可以了
//
//    感悟:
//
//        这道题,开始的时候,从正面做,看减去什么,但是最后都是把自己脑子搞糊涂
//    了,不知道自己在干什么,最后,就没有最后了,每次做题,都是这种感觉,看到解答
//    的时候,我才恍然大悟,原来可以这样啊,自己缺乏抽象思维,缺乏转换问题的思维
//    多说也没什么用,继续加油吧!FIGHTING

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>

using namespace std;

typedef long long ll;

const int MAX_N = 500;
const ll MOD = 1000007;
ll C[MAX_N][MAX_N];
int n,m,k;
void init(){
    C[0][0] = 1;
    for (int i=1;i<MAX_N;i++){
        C[i][0] = C[i][i] = 1;
        for (int j=1;j<i;j++)
            C[i][j] = (C[i-1][j-1] + C[i-1][j])%MOD;
    }
}

void input(){

    scanf("%d%d%d",&n,&m,&k);
    ll sum = 0;
    for (int S=0;S<16;S++){
        int b = 0,r = n,c = m;
        if(S & 1){
            r--;
            b++;
        }
        if (S & 2){
            r--;
            b++;
        }
        if (S & 4){
            c--;
            b++;
        }
        if (S & 8){
            c--;
            b++;
        }
        if (b & 1)
            sum = (sum + MOD - C[r * c][k])%MOD;
        else 
            sum = (sum + C[r * c][k])%MOD;
    }
    cout << sum << endl;
}

int main(){

    int t;
    init();
    //freopen("1.txt","r",stdin);
    scanf("%d",&t);
    int kase = 1;
    while(t--){
        printf("Case %d: ",kase++);
        input();
    }
}

 

posted on 2015-08-05 14:49  KingJourney  阅读(186)  评论(0)    收藏  举报