QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#684283#1185. To argue, or not to arguerlc202204AC ✓2760ms10128kbC++173.0kb2024-10-28 12:10:102024-10-28 12:10:11

Judging History

This is the latest submission verdict.

  • [2024-10-28 12:10:11]
  • Judged
  • Verdict: AC
  • Time: 2760ms
  • Memory: 10128kb
  • [2024-10-28 12:10:10]
  • Submitted

answer

#include <iostream>
#include <cstdio>
#include <vector>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 14;
const int mod = 1e9 + 7;
const int MS = (1 << 12) + 5;

int fpow(int a, int b, int p) {
	if (b == 0)
		return 1;
	int ans = fpow(a, b / 2, p);
	ans = 1ll * ans * ans % p;
	if (b % 2 == 1)
		ans = 1ll * a * ans % p;
	return ans; 
}
int mmi(int a, int p) {
	return fpow(a, p - 2, p);
}
int fac[N * N] = {0}, inv[N * N] = {0};
void init(int n) {
	fac[0] = 1;
	for (int i = 1; i <= n; i++)
		fac[i] = 1ll * i * fac[i - 1] % mod;
	inv[n] = mmi(fac[n], mod);
	for (int i = n - 1; i >= 0; i--)
		inv[i] = 1ll * (i + 1) * inv[i + 1] % mod; 
}
int A(int n, int k) {
	return 1ll * fac[n] * inv[n - k] % mod; 
}

void add(int &x, int y) {
	x = (x + y) % mod;
}

int n, m, k;
char mp[N * N][N * N], mp2[N * N][N * N];

int f[N * N][MS] = {{0}};
int f2[N * N][MS] = {{0}};

void show(int S) {
	for (int j = 0; j < n; j++)
		cout << (S >> j & 1); 
}

int tmp[N * N] = {0}, len = 0;

void dfs(int x, int col, int S, int nS, int cnt) {//当前是第 x 个,第 col 列,上一列是 S,这一列目前是 nS,用了 cnt 个了 
	if (x > n) {
		for (int j = 1; j <= len && tmp[j] + cnt <= k; j++)
			add(f[tmp[j] + cnt][nS], f2[tmp[j]][S]);
		return;
	}
	if ((S >> (x - 1) & 1)) {//被预定了 
		if (mp[x][col] != 'X')
			dfs(x + 1, col, S, nS, cnt + 1);
	}
	else if (mp[x][col] == 'X') {
		dfs(x + 1, col, S, nS, cnt);
	}
	else {
		if (x < n && mp[x + 1][col] != 'X' && !(S >> x & 1)) {
			dfs(x + 2, col, S, nS, cnt + 1);
		}
		dfs(x + 1, col, S, nS, cnt);
		dfs(x + 1, col, S, nS + (1 << (x - 1)), cnt);
	}
}

int pw[N * N] = {0};

void slv() {
	scanf("%d%d%d", &n, &m, &k);
	init(n * m);
	int cnt = 0;
	for (int i = 1; i <= n; i++)	
		for (int j = 1; j <= m; j++)
			scanf(" %c", &mp[i][j]), cnt += (mp[i][j] == '.');	
	if (n > m) {
		swap(n, m);
		for (int i = 1; i <= n; i++)
			for (int j = 1; j <= m; j++)
				mp2[i][j] = mp[j][i];
		for (int i = 1; i <= n; i++)
			for (int j = 1; j <= m; j++)
				mp[i][j] = mp2[i][j];
	}
	memset(f, 0, sizeof f);
	f[0][0] = 1;
	for (int i = 0; i < m; i++) {
		memcpy(f2, f, sizeof f2);
		memset(f, 0, sizeof f);
		for (int S = 0; S < (1 << n); S++) {
			len = 0;
			for (int j = 0; j <= i * n / 2; j++)
				if (f2[j][S] > 0) 
					tmp[++len] = j;		
			if (len > 0)
				dfs(1, i + 1, S, 0, 0);
		}
	} 
	pw[0] = 1;
	for (int i = 1; i <= k; i++)
		pw[i] = 2ll * pw[i - 1] % mod;
	int ans = 0;
	for (int i = 0; i <= k; i++)	
		if (i % 2 == 0) {
	//		cout << i << " ? " << f[m][i][0] << endl;
			add(ans, 1ll * f[i][0] * A(k, i) % mod * pw[i] % mod * A(cnt - i * 2, 2 * k - 2 * i) % mod);
		}
		else {
	//		cout << i << " ? " << f[m][i][0] << endl;
			add(ans, (mod - 1ll * f[i][0] * A(k, i) % mod * pw[i] % mod * A(cnt - i * 2, 2 * k - 2 * i) % mod) % mod);
		}
	printf("%d\n", ans);
}

int main() {
//	freopen("test.in", "r", stdin);
	int T;
	scanf("%d", &T);
	while (T--)
		slv();	
	return 0;
} 

详细

Test #1:

score: 100
Accepted
time: 4ms
memory: 10084kb

input:

2
2 2 2
..
..
4 4 3
X.X.
....
.X..
...X

output:

8
347040

result:

ok 2 number(s): "8 347040"

Test #2:

score: 0
Accepted
time: 2760ms
memory: 10128kb

input:

96
1 144 8
................................................................................................................................................
144 1 31
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
....

output:

517668733
268886110
64664470
926220403
0
0
372341012
839870997
115795952
169129272
928175112
399452284
981581814
563968454
82030165
770277954
161484719
374884294
988612558
269599606
838995341
614914000
779550646
19224822
195892020
368899964
857064056
437999888
225342223
836336621
981420655
30328633
...

result:

ok 96 numbers