2024-12-05-csp-js-2024-r2-chain-solution
CSP-J/S 2024 第二轮 入门级 接龙 题解
题目来源:ET题库 - 接龙
题目分析
这是一道关于序列接龙的题目。主要需要考虑以下几点:
- 每个人有自己的词库(整数序列)
- 需要判断是否能在指定轮数内完成接龙
- 接龙时需要考虑数字的连接关系
解题思路
- 首先需要存储每个人的词库
- 对于每个查询,我们需要判断是否能在给定轮数内完成接龙
- 使用动态规划来解决这个问题
代码实现
#include <bits/stdc++.h> using namespace std; const int MAXN = 1005; const int MAXK = 1005; vector<int> wordbank[MAXN]; // 存储每个人的词库 int n, k, q; // n个人,k轮,q个查询 // 判断是否可以完成接龙 bool can_chain(int rounds, int target) { // dp[i][j] 表示第i轮使用第j个数是否可行 vector<vector<bool>> dp(rounds + 1, vector<bool>(MAXK, false)); // 初始化第一轮 for (int num : wordbank[1]) { dp[1][num] = true; } // 动态规划 for (int i = 1; i < rounds; i++) { for (int j = 1; j <= k; j++) { if (!dp[i][j]) continue; // 尝试接下一个数 for (int next : wordbank[(i % n) + 1]) { if (next == j) { dp[i + 1][next] = true; } } } } // 检查最后一轮是否能达到目标 return dp[rounds][target]; } int main() { freopen("chain.in", "r", stdin); freopen("chain.out", "w", stdout); // 读入数据 cin >> n >> k >> q; for (int i = 1; i <= n; i++) { int li; cin >> li; wordbank[i].resize(li); for (int j = 0; j < li; j++) { cin >> wordbank[i][j]; } } // 处理查询 while (q--) { int r, c; cin >> r >> c; cout << (can_chain(r, c) ? 1 : 0) << endl; } return 0; }
代码解释
1. 数据结构
vector<int> wordbank[MAXN]; // 存储每个人的词库
使用vector数组存储每个人的词库,方便访问和管理。
2. 动态规划部分
vector<vector<bool>> dp(rounds + 1, vector<bool>(MAXK, false));
dp[i][j]
表示第i轮使用第j个数是否可行- 通过两层循环来填充dp数组
- 对于每个可行状态,尝试接下一个数
3. 查询处理
while (q--) { int r, c; cin >> r >> c; cout << (can_chain(r, c) ? 1 : 0) << endl; }
对每个查询调用can_chain函数判断是否可行。
时间复杂度分析
- 预处理:O(n)
- 每次查询:O(rounds * k * max_wordbank_size)
- 总体复杂度:O(q * k * n * max_wordbank_size)
注意事项
- 文件输入输出
freopen("chain.in", "r", stdin); freopen("chain.out", "w", stdout);
- 边界条件处理
- 注意检查rounds和target的合法性
- 考虑特殊情况(如第一轮)
总结
这道题是一个典型的动态规划问题,关键在于:
- 正确定义状态
- 找到状态转移方程
- 合理处理边界条件
希望这个题解对你有帮助!如果有任何问题,欢迎在评论区讨论。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步