AcWing 6041. 接龙
原题链接
困难
作者:
ranba
,
2024-11-09 08:12:19
,
所有人可见
,
阅读 8
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1e5, MAXNUM = 2e5; //最多的人数,最大的数字
int n, k, q;
vector <int> a[MAXN + 9]; //a[i]存储第i个人的词库
int f[109][MAXNUM + 9]; //f[r][c]={-1, 0, i}分别表示第r轮接龙以数字c结尾{不可行,可以在多个人处结尾,可以在第i个人处结尾}
void solve() {
memset(f, -1, sizeof(f));
cin >> n >> k >> q;
for (int i = 1; i <= n; i ++) {
a[i].clear(); //将第i个人的词库清空
int l, s;
cin >> l;
while (l --) {
cin >> s;
a[i].push_back(s);
} //a[i].size()是第i个人的词库长度
}
f[0][1] = 0; //数字1在每一行都可以作为新一轮接龙的开头
for (int r = 1; r <= 100; r ++) { //枚举第r轮接龙
for (int i = 1; i <= n; i ++) { //枚举第i个人
//将第i个人词库前面的某些数字作为第r轮接龙的开头,它们能管到的最远位置
int maxpos = -1;
for (int j = 0; j < a[i].size(); j ++) {
int t = a[i][j]; //第i个人词库里的第j个数字:t
//检查第j个数字能否作为第r轮接龙的结尾
if (j <= maxpos) { //注意"龙"的长度 >= 2,所以第0个数字不能作为"龙"的结尾(0 <= -1不成立)
if (f[r][t] == -1) { //数字t之前没有做过第r轮的结尾
f[r][t] = i; //数字t在第i个人这里可以作为第r轮的结尾
}
else if (f[r][t] > 0 && f[r][t] != i) {
f[r][t] = 0; //数字t可以在多个人(>=2)处作为第r轮的结尾
}
}
if (f[r - 1][t] != -1 && f[r - 1][t] != i) { //数字t在其他人处可以作为上一轮接龙的结尾
maxpos = max(maxpos, j + k - 1); //数字t可以作为第r轮接龙的开头
}
}
}
}
while (q --) {
int r, c;
cin >> r >> c;
if (f[r][c] == -1) cout << 0 << '\n';
else cout << 1 << '\n';
}
}
int main() {
ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
int T; cin >> T;
while (T --) solve();
return 0;
}