QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#508669 | #7623. Coloring Tape | manhao | RE | 1ms | 7780kb | C++20 | 3.3kb | 2024-08-07 18:57:49 | 2024-08-07 18:57:49 |
Judging History
answer
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define N 20
#define M 1000
int n, m, q;
int dif_color[M][N][N];
int cnt[(1 << 14) + 50]; // s状态里有多少刷子
int top;
int qq[N]; // 第i个刷子在第几个格子
int bs[(1 << 14) + 50][N]; // bs[s][i]s状态第i个刷子在哪个格子
int cur;
vector<int> to[(1 << 14) + 50];
void dfs(int i, int r, int s) // 第i个刷子,该刷第r+1个格 ,状态s
{
if (i > top)
{
if (r == n)
to[cur].push_back(s); // cur能从s刷到
return;
}
if (qq[i] == r + 1) // 刷子在第r+1格可以是从上面下来的
{
for (int k = qq[i]; k <= qq[i + 1] - 1; k++)
{
dfs(i + 1, k, s | 1 << (k - 1));
}
}
else
dfs(i + 1, qq[i], s | (1 << r)); // 否则是从下面上去的
}
int check(int i, int l, int r)
{
if (l > r)
swap(l, r);
return dif_color[i][l][r];
}
int dp[20][1 << 14] = {0};
#define mod 998244353
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cin >> n >> m >> q;
for (int i = 1; i <= q; i++)
{
int c, x, y, diff;
cin >> c >> x >> y >> diff;
if (diff == 1)
{
for (int l = 1; l <= n; l++)
{
for (int r = l; r <= n; r++)
{
if (l <= x && y <= r)
{
dif_color[c][l][r] = 1; // l,r必须是不同颜色
}
}
}
}
else
{
for (int l = 1; l <= n; l++)
{
for (int r = l; r <= n; r++)
{
if ((l <= x && x <= r) != (l <= y && y <= r))
{
dif_color[c][l][r] = 1; // l,r必须是不同颜色
}
}
}
}
}
for (int s = 1; s <= (1 << n) - 1; s++)
{
top = 0;
cur = s;
for (int j = 0; j <= n - 1; j++)
{
if ((1 << j) & s)
qq[++top] = j + 1, bs[s][++cnt[s]] = j + 1;
}
qq[top + 1] = n + 1; // 刷子上界
dfs(1, 0, 0);
}
for (int s = 1; s <= (1 << n) - 1; s++)
{
dp[m][s] = 1;
}
for (int i = m; i >= 2; i--)
{
for (int s = 1; s <= (1 << n) - 1; s++)
{
for (auto s2 : to[s])
{
int flag = 1;
for (int k = 1; k <= cnt[s]; k++)
{
if (check(i, bs[s][k], bs[s2][k]))
{
flag = 0;
break;
}
}
if (flag)
dp[i - 1][s] = (dp[i - 1][s] + dp[i][s2]) % mod;
}
}
for (int j = 0; j <= n - 1; j++)
{
for (int s = 1; s <= (1 << n) - 1; s++)
{
if (s & (1 << j))
{
dp[i - 1][s] = (dp[i - 1][s] + dp[i - 1][s - (1 << j)]) % mod; // 子集的和 前缀和
}
}
}
}
cout << dp[1][(1 << n) - 1] << endl;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 1ms
memory: 7748kb
input:
3 5 3 3 2 3 0 4 1 2 0 5 1 3 0
output:
19
result:
ok 1 number(s): "19"
Test #2:
score: 0
Accepted
time: 1ms
memory: 7780kb
input:
5 10 10 9 3 4 1 2 4 5 0 7 2 3 0 9 2 3 0 6 3 5 0 6 2 4 1 2 4 5 0 1 1 3 1 7 2 4 0 10 2 3 0
output:
1514
result:
ok 1 number(s): "1514"
Test #3:
score: 0
Accepted
time: 0ms
memory: 7704kb
input:
5 10 20 8 4 5 0 2 2 5 1 8 4 5 0 10 3 5 0 7 1 3 1 1 2 4 1 6 3 5 1 10 3 5 0 4 1 5 1 7 3 4 1 2 2 4 1 8 3 4 0 9 3 5 0 5 2 5 1 9 4 5 0 9 1 2 0 6 1 5 1 8 3 5 0 2 2 4 1 8 3 5 0
output:
28131
result:
ok 1 number(s): "28131"
Test #4:
score: -100
Runtime Error
input:
10 100 200 95 5 7 0 7 4 6 1 62 9 10 0 32 5 8 1 31 2 6 1 75 7 9 1 1 4 7 1 18 7 10 1 75 1 8 1 87 6 9 1 44 7 8 1 68 6 9 1 95 4 6 0 34 1 2 1 70 1 6 1 31 5 9 1 15 6 10 1 48 5 8 1 51 3 7 1 39 5 9 1 23 2 3 1 7 8 9 1 84 7 10 1 13 4 9 1 18 3 6 1 59 9 10 0 31 8 10 1 6 7 9 1 76 3 10 1 41 5 6 0 33 3 4 1 96 1 10...