QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#326413 | #2576. 麻将 | luyiming123 | 80 | 1965ms | 21720kb | C++23 | 5.3kb | 2024-02-13 00:23:24 | 2024-02-13 00:23:26 |
Judging History
answer
# include <bits/stdc++.h>
# define int long long
using namespace std;
const int N = 105, mod = 998244353;
void Add(int &x, int y) {x = (1ll * x + y) % mod; return; }
int n, buc[N];
void chkmax(int &x, int y) { x = max(x, y); return; }
struct node
{
int dp[2][3][3], tot; // 有没有对子;(i-1,i,i+1)个数;(i,i+1,i+2)个数;对子个数
void Init(void)
{
for(int o : {0, 1})
for(int i : {0, 1, 2})
for(int j : {0, 1, 2})
dp[o][i][j] = -1;
tot = 0;
return;
}
void Init0(void) // all 0
{
Init();
dp[0][0][0] = 0; return;
}
bool check(void)
{
if(tot >= 7) return 1;
for(int i = 0; i <= 2; i++)
for(int j = 0; j <= 2; j++)
if(dp[1][i][j] >= 4) return 1;
return 0;
}
void print(void)
{
printf("tot = %lld\n", tot);
for(int o : {0, 1})
{
for(int i = 0; i <= 2; i++)
{
for(int j = 0; j <= 2; j++)
{
printf("%3d", dp[o][i][j]);
}
printf("\n");
}
printf("\n");
}
printf("\n");
}
};
bool operator < (const node &x, const node &y)
{
if(x.tot != y.tot) return x.tot < y.tot;
for(int i = 0; i <= 1; i++)
for(int j = 0; j <= 2; j++)
for(int k = 0; k <= 2; k++)
if(x.dp[i][j][k] != y.dp[i][j][k]) return x.dp[i][j][k] < y.dp[i][j][k];
return 0;
}
node Trans(node &X, int t)
{
node Ans; Ans.Init();
for(int o : {0, 1})
{
for(int i = 0; i <= 2; i++)
{
for(int j = 0; j <= 2; j++)
{
if(X.dp[o][i][j] == -1) continue;
for(int a1 = 0; a1 <= min(t, i); a1++)
{
for(int a2 = 0; a2 <= min(t - a1, j); a2++)
{
for(int a3 = 0; a3 <= min(2ll, t - a1 - a2); a3++)
{
int a4 = t - a1 - a2 - a3;
int ni = a2, nj = a3;
if(o == 0 && a4 >= 2)
{
chkmax(Ans.dp[1][ni][nj], min(4ll, X.dp[0][i][j] + a1));
}
chkmax(Ans.dp[o][ni][nj], min(4ll, X.dp[o][i][j] + a1 + (a4 >= 3)));
}
}
}
}
}
}
Ans.tot = X.tot + (t >= 2);
return Ans;
}
map <node, int> Tong; int idtot = 0;
int to[5][3005];
void bfs(void)
{
// vector <node> Sts; Sts.
queue <node> Q; node St; St.Init0();
Q.push(St); Tong[St] = ++idtot;
while(!Q.empty())
{
auto I = Q.front(); Q.pop();
for(int t = 0; t <= 4; t++)
{
auto New = Trans(I, t);
if(New.check()) to[t][Tong[I]] = 0;
else
{
if(!Tong.count(New)) Tong[New] = ++idtot, Q.push(New);
to[t][Tong[I]] = Tong[New];
}
}
}
return;
}
int f[2][N << 2][3005], fac[N << 2], ifac[N << 2];
int qpow(int x, int p = mod - 2ll)
{
int ans = 1ll;
while(p)
{
if(p & 1) ans = 1ll * ans * x % mod;
x = 1ll * x * x % mod, p >>= 1;
}
return ans;
}
void Init(int n = 405)
{
fac[0] = ifac[0] = 1;
for(int i = 1; i <= n; i++) fac[i] = 1ll * fac[i - 1] * i % mod;
ifac[n] = qpow(fac[n]);
for(int i = n - 1; i >= 1; i--) ifac[i] = ifac[i + 1] * (i + 1ll) % mod;
return;
}
int C(int n, int m)
{
if(n < m) return 0;
return 1ll * fac[n] * ifac[m] % mod * ifac[n - m] % mod;
}
signed main(void)
{
Init();
scanf("%lld", &n);
for(int i = 1; i <= 13; i++)
{
int w, t; scanf("%lld%lld", &w, &t); ++buc[w];
}
bfs();
// fprintf(stderr, "idtot = %lld\n", idtot);
f[0][0][1] = 1;
for(int i = 0; i < n; i++)
{
// int o = (i & 1), l1 = min(4 * (i + 1), 4 * n - 13), l0 = min(4 * i, 4 * n - 13);
int o = (i & 1), l0 = 4 * n - 13, l1 = l0;
for(int j = 0; j <= l1; j++)
{
for(int s = 0; s <= idtot; s++) f[o ^ 1][j][s] = 0;
}
for(int j = 0; j <= l0; j++)
{
for(int s = 0; s <= idtot; s++)
{
for(int t = 0; t <= 4 - buc[i + 1]; t++) // (i + 1) choose t
{
if(j + t <= l1)
{
Add(f[o ^ 1][j + t][to[t + buc[i + 1]][s]], 1ll * f[o][j][s] * C(4 - buc[i + 1], t) % mod);
}
}
}
}
}
int Ans = 0;
for(int j = 1; j <= 4 * n - 13; j++)
{
int sum = 0;
for(int s = 1; s <= idtot; s++) // 不胡
{
Add(sum, f[n & 1][j][s]);
}
// printf("j = %lld, sum = %lld\n", j, sum);
Add(Ans, 1ll * sum * fac[j] % mod * fac[(4 * n - 13) - j] % mod);
}
Ans = 1ll * Ans * ifac[4 * n - 13] % mod; Ans = (Ans + 1ll) % mod;
printf("%lld\n", Ans);
return 0;
}
详细
Test #1:
score: 10
Accepted
time: 7ms
memory: 6544kb
input:
5 1 1 1 2 1 3 1 4 2 1 3 1 3 2 3 3 3 4 5 1 5 2 5 3 5 4
output:
570425346
result:
ok single line: '570425346'
Test #2:
score: 10
Accepted
time: 7ms
memory: 6532kb
input:
5 1 3 2 4 4 3 5 3 3 1 5 4 4 2 1 4 4 4 3 3 3 2 1 1 2 2
output:
713031682
result:
ok single line: '713031682'
Test #3:
score: 10
Accepted
time: 26ms
memory: 7464kb
input:
13 1 3 12 1 12 2 1 4 13 3 13 2 3 2 13 1 1 1 3 4 3 3 1 2 12 3
output:
868236068
result:
ok single line: '868236068'
Test #4:
score: 10
Accepted
time: 31ms
memory: 7404kb
input:
13 1 1 13 1 2 3 1 3 3 1 3 4 2 1 13 4 1 4 12 2 13 3 12 3 3 2
output:
234399821
result:
ok single line: '234399821'
Test #5:
score: 10
Accepted
time: 26ms
memory: 7192kb
input:
13 2 3 2 1 12 2 13 2 2 2 1 2 13 3 12 4 13 4 3 4 3 1 12 3 1 3
output:
892522858
result:
ok single line: '892522858'
Test #6:
score: 10
Accepted
time: 1443ms
memory: 18868kb
input:
81 1 1 2 1 3 1 4 1 5 1 6 1 7 1 8 1 9 1 10 1 11 1 12 1 13 1
output:
152635587
result:
ok single line: '152635587'
Test #7:
score: 10
Accepted
time: 1965ms
memory: 21720kb
input:
94 1 1 2 1 3 1 4 1 5 1 6 1 7 1 8 1 9 1 10 1 11 1 12 1 13 1
output:
339459976
result:
ok single line: '339459976'
Test #8:
score: 0
Time Limit Exceeded
input:
96 1 2 1 3 1 4 1 1 2 2 2 3 2 4 2 1 3 2 3 3 3 4 3 1 4 2
output:
230028597
result:
Test #9:
score: 10
Accepted
time: 1510ms
memory: 19012kb
input:
83 1 2 1 3 1 4 1 1 2 2 2 3 2 4 2 1 3 2 3 3 3 4 3 1 4 2
output:
967250236
result:
ok single line: '967250236'
Test #10:
score: 0
Time Limit Exceeded
input:
100 67 1 26 4 12 4 11 4 30 4 29 1 1 4 13 3 30 1 64 2 63 1 20 2 32 4