车的放置

// 车的放置.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//



/*

http://ybt.ssoier.cn:8088/problem_show.php?pid=1654

https://loj.ac/p/10232

有下面这样的一个网格棋盘,a,b,c,d 表示了对应边长度,也就是对应格子数。

当 a=b=c=d=2 时,对应下面这样一个棋盘:

要在这个棋盘上放 k 个相互不攻击的车,也就是这 k 个车没有两个车在同一行,也没有两个车在同一列,问有多少种方案。
同样只需要输出答案 mod105+3 后的结果。

【输入】
第一行为有五个非负整数 a,b,c,d 和 k。

【输出】
包括一个正整数,为答案 mod105+3 后的结果。

【输入样例】
2 2 2 2 2
【输出样例】
38
【提示】
数据范围与提示:

对于全部数据,1≤a,b,c,d,k≤1000,且保证了至少有一种可行方案。
*/
#include <iostream>

using namespace std;

const int N = 2010;
long long fact[N], infact[N];
int a, b, c, d, k;
const int mod = 1e5 + 3;

long long qmi(long long a, long long b) {
	long long res = 1;
	while (b) {
		if (b & 1) res = res * a % mod;
		a = a * a % mod;
		b >>= 1;
	}
	return res;
}


void init() {
	fact[0] = 1; infact[0] = 1;
	for (int i = 1; i < N; i++) {
		for (int j = 0; j < N; j++) {
			fact[i] = fact[i-1] * i % mod;
			infact[i] = infact[i - 1] * qmi(i, mod - 2) % mod;
		}
	}
}


long long C(int a, int b) {
	if (b > a) return 0;
	return fact[a] * infact[a - b]%mod*infact[b]%mod;

}

long long P(int a, int b) {
	if (b > a) return 0;
	return fact[a] * infact[a - b]%mod;
}
 

int main() {
	cin >> a >> b >> c >> d >> k;
	init();
	long long res = 0;
	for (int i = 0; i <= k; i++) {
		int nk = k - i;
		res = res + (C(b, i) * P(a, i) % mod) * (C(d, nk) * P(a + c - i, nk) % mod) % mod;
		res %= mod;
	}

	cout << res << endl;

	return 0;
}

posted on 2025-03-31 17:42  itdef  阅读(13)  评论(0)    收藏  举报

导航