题解:
1.汝佳哥容斥的漂亮
2.我是分情况讨论的,所有情况抛去有一条(行或者列)没有石子的,再抛去两条,三条,和四条的
总结:
1.除了那些特别有把握的题目以外,都要尝试一些小的数据。
2.思考问题时要整齐的用草稿纸,以保证良好的解题思路!
我的代码
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
#define MAXN 505
#define MOD 1000007
int n,m,k,_,c[MAXN][MAXN];
int solve()
{
if(k > n * m)return 0;
int minn = c[(m - 2) * (n - 2)][k];
int a1 = 2 * (c[(n - 1) * (m - 2)][k] - minn);
int a2 = 2 * (c[(n - 2) * (m - 1)][k] - minn);
int b1 = c[n * (m - 2)][k] - minn - a1;
int b2 = c[(n - 2) * m][k] - a2 - minn;
int c1 = 4 * (c[(m - 1) * (n - 1)][k] - a1 / 2 - a2 / 2 - minn);
int d1 = 2 * (c[m * (n - 1)][k] - b2 - a1 / 2 - a2 - c1 / 2 - minn);
int d2 = 2 * (c[(m - 1) * n][k] - b1 - a2 / 2 - a1 - c1 / 2 - minn);
return ((c[n * m][k] - a1 - a2 - b1 - b2 - c1 - d1 - d2 - minn) % MOD + MOD) % MOD;
}
int main()
{
scanf("%d",&_);
for(int i = 0;i < MAXN;i++)c[i][0] = 1;
for(int i = 1;i < MAXN;i++)
for(int j = 1;j < MAXN;j++)
c[i][j] = (c[i - 1][j - 1] + c[i - 1][j]) % MOD;
int kcas = 0;
while(_--)
{
scanf("%d%d%d",&n,&m,&k);
int ans = solve();
printf("Case %d: %d\n",++kcas,ans);
}
}
汝佳哥的代码:
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
#define MAXN 505
#define MOD 1000007
int n,m,k,_,c[MAXN][MAXN];
int solve()
{
if(k > n * m)return 0;
int ans = 0;
for(int i = 0;i < 16;i++)
{
int a = n,b = m,d = 0;
if(i & 1)
{
a--;
d++;
}
if(i & 2)
{
a--;
d++;
}
if(i & 4)
{
b--;
d++;
}
if(i & 8)
{
b--;
d++;
}
if(d & 1)ans -= c[a * b][k];
else ans += c[a * b][k];
}
//cout << ans << " ans " << endl;
return (ans % MOD + MOD) % MOD;
}
int main()
{
scanf("%d",&_);
for(int i = 0;i < MAXN;i++)c[i][0] = 1;
for(int i = 1;i < MAXN;i++)
for(int j = 1;j < MAXN;j++)
c[i][j] = (c[i - 1][j - 1] + c[i - 1][j]) % MOD;
int kcas = 0;
while(_--)
{
scanf("%d%d%d",&n,&m,&k);
int ans = solve();
printf("Case %d: %d\n",++kcas,ans);
}
}