题解:P11230 [CSP-J 2024] 接龙(暂无数据)
4041nofoundGeoge · · 题解
特别难的题!
思路
我们把所有人的序列依次排列成的一个序列设为
当我们看到
我们可以把一轮接龙的过程分成两步:先选择一个和上一次接龙未尾数字相同的起始点,在选择一个满足是同一个人,且位置相差在
这样,我们发现,第一步只和每个位置上的数字有关,而第二步只和位置有关。因此我们可以把转移分成两步,先根据上一轮的
我们再设
现在我们想如何利用
其中
但是题目要求两轮接龙不能使用同一个人的序列,而
其中
综上我们可以在
代码
#include <bits/stdc++.h>
#define N 200100
#define M 110
using namespace std;
int T, n, K, Q, ok[M][N];
vector<int> num[N];
int main()
{
cin >> T;
while (T--)
{
memset(ok, -1, sizeof(ok));
scanf("%d%d%d", &n, &K, &Q);
for (int i = 1; i <= n; i++)
{
num[i].clear();
int len;
scanf("%d", &len);
for (int j = 1; j <= len; j++)
{
int t;
scanf("%d", &t);
num[i].push_back(t);
}
}
ok[0][1] = 0;
for (int T = 1; T <= 100; T++)
{
for (int i = 1; i <= n; i++)
{
int len = 0;
for (auto t : num[i])
{
len = max(len - 1, 0);
if (len)
{
if (ok[T][t] == -1)
ok[T][t] = i;
else if (ok[T][t] && ok[T][t] != i)
ok[T][t] = 0;
}
if (ok[T - 1][t] != -1 && ok[T - 1][t] != i)
len = K;
}
}
}
while (Q--)
{
int p, q;
scanf("%d%d", &p, &q);
puts(ok[p][q] != -1 ? "1" : "0");
}
}
}//update:2024.10.29