题意
给一个m行n列的方阵,然后在这些方阵里面放k个石子,问第一行,第一列,最后一行,最后一列都必须有石子的方案有多少种
分析
这里我们假设第一行,第一列,最后一行,最后一列不放石子的方案分别为A,B,C,D。那么由容斥原理可以得到题目要求的总量等于
ANS=SUM−(A+B+C+D)+(AB+AC+AD+BC+BD+CD)−(ABC+ABD+ACD+BCD)+(ABCD)
A
N
S
=
S
U
M
−
(
A
+
B
+
C
+
D
)
+
(
A
B
+
A
C
+
A
D
+
B
C
+
B
D
+
C
D
)
−
(
A
B
C
+
A
B
D
+
A
C
D
+
B
C
D
)
+
(
A
B
C
D
)
有这个我们画个图看下这些情况的交集是什么就好了。
开始的时候没有这么分析,导致加减的时候集合算错了。所以说简单题也要细心= =
还有一点就是comb不要开ll,re了几发很难受- -
代码
#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
const ll mod = 1000007;
const int N = 505;
int comb[N][N];
int main()
{
for (int i = 0; i <= N; i++) {
comb[i][0] = comb[i][i] = 1;
for (int j = 1; j < i; j++) {
comb[i][j] = comb[i - 1][j] + comb[i - 1][j - 1];
comb[i][j] %= mod;
}
}
int t, ca = 1;
cin >> t;
while (t--)
{
int m, n, k;
cin >> m >> n >> k;
ll ans1 = 0, ans2 = 0, ans3 = 0, ans4 = 0, ans5 = 0, ans = 0;
ans1 = comb[m*n][k];
ans2 = (2 * (comb[(m - 1)*n][k] + comb[(n - 1)*m][k])) % mod;
ans3 = (4 * comb[(m - 1)*(n - 1)][k] + comb[(m - 2)*n][k] + comb[(n - 2)*m][k]) % mod;
ans4 = (2 * (comb[(m - 2)*(n - 1)][k] + comb[(m - 1)*(n - 2)][k])) % mod;
ans5 = (comb[(m - 2)*(n - 2)][k]) % mod;
ans = (ans1 - ans2 + ans3 - ans4 + ans5 + 2 * mod) % mod;;
cout << "Case " << ca++ << ": " << ans << endl;
}
return 0;
}