Code jam 2022 Round 1C Letter Blocks
https://codingcompetitions.withgoogle.com/codejam/round/0000000000877b42/0000000000afe6a1#analysis
一道复杂的字符串拼接模拟题。
可以考虑对每个字符串进行预处理。
如果在middle的字符在其他字符串中出现过,则impossible。
如果字符在其他字符串的middle中出现过,则impossible。
然后可以将字符串简化为X或XY类型,并用map记录。
同时注意,不能同时出现XY1和XY2,以及X1Y和X2Y类型。(因为这样则一定无法拼接)。
之后可以对首字符串进行选取选取规则为,若选取X1Y1类型,则不能存在剩余的X1类型以及X2X1类型,若选取X1类型,则不能存在X2X1类型。(因为如果存在,则必须放在其前面)。
选取首字符串后,则可以进行拼接,对X1Y1,先遍历Y1,再遍历Y1Y2。当选取完全部字符串就可以进行输出。
如果遍历选择后,如果新的结尾字符和旧的结尾字符相同,且没有选取完字符串,则接下来重新按选取首字符串的规则进行选取。
直到选取完全部字符串。
代码如下

#include<bits/stdc++.h> using namespace std; int m_index = 0; string cur_str; void YD() { m_index++; cur_str.clear(); int n; cin >> n; vector<string> all_str(n); for (int i = 0; i < n; i++) cin >> all_str[i]; bool vis[26] = {false}; bool vis_mid[26] = { false }; map<char, vector<int>> ch_index; map<char, vector<int>> start_index; map<char, vector<int>> end_index; for (int index = 0; index < n; index++) { auto &str = all_str[index]; int nn = str.size(); int i = 0, j = nn - 1; if (vis_mid[str[i] - 'A']) { cout << "Case #" << m_index << ": " << "IMPOSSIBLE" << endl; return; } if (vis_mid[str[j] - 'A']) { cout << "Case #" << m_index << ": " << "IMPOSSIBLE" << endl; return; } while (i < nn - 1 && str[i + 1] == str[i]) i++; while (j > 0 && str[j - 1] == str[j]) j--; if (j <= i) { vis[str[i]-'A'] = true; ch_index[str[i]].push_back(index); continue; } if (str[i] == str[j] && i < j) { cout << "Case #" << m_index << ": " << "IMPOSSIBLE" << endl; return; } vis[str[i] - 'A'] = true; vis[str[j] - 'A'] = true; start_index[str[i]].push_back(index); if (start_index[str[i]].size() != 1) { cout << "Case #" << m_index << ": " << "IMPOSSIBLE" << endl; return; } end_index[str[j]].push_back(index); if (end_index[str[j]].size() != 1) { cout << "Case #" << m_index << ": " << "IMPOSSIBLE" << endl; return; } while (++i < j) { if (vis[str[i] - 'A'] && str[i] != str[i - 1]) { cout << "Case #" << m_index << ": " << "IMPOSSIBLE" << endl; return; } vis[str[i] - 'A'] = true; vis_mid[str[i] - 'A'] = true; } } int first = -1; for (auto &[ch, v_i] : start_index) { if (end_index.count(ch) == 0 && ch_index.count(ch) == 0) { first = v_i[0]; break; } } if (first == -1) { for (auto &[ch, i] : ch_index) { if (end_index.count(ch) == 0) { first = i[0]; break; } } } if (first == -1) { cout << "Case #" << m_index << ": " << "IMPOSSIBLE" << endl; return; } vector<bool> vi(n, false); vi[first] = true; vector<int> res; res.push_back(first); char cur_end = all_str[first].back(); while (res.size() < n) { char prev_end = cur_end; if (ch_index.count(cur_end)) { for (auto ii : ch_index[cur_end]) { if (vi[ii]) { continue; } else { vi[ii] = true; res.push_back(ii); } } } if (res.size() == n) break; if (start_index.count(cur_end)) { for (auto ii : start_index[cur_end]) { if (vi[ii]) { continue; } else { vi[ii] = true; res.push_back(ii); cur_end = all_str[ii].back(); } } } if (res.size() == n) break; if (cur_end == prev_end) { first = -1; for (auto &[ch, v_i] : start_index) { if (!vi[v_i[0]] && end_index.count(ch) == 0 && ch_index.count(ch) == 0) { first = v_i[0]; break; } } if (first == -1) { for (auto &[ch, i] : ch_index) { if (!vi[i[0]]&&end_index.count(ch) == 0) { first = i[0]; break; } } } if (first == -1) { cout << "Case #" << m_index << ": " << "IMPOSSIBLE" << endl; return; } vi[first] = true; res.push_back(first); cur_end = all_str[first].back(); } } if (res.size() == n) { cout << "Case #" << m_index << ": "; for (auto i : res) { cout << all_str[i]; } cout << endl; } } int main() { int T; cin >> T; while (T--) { YD(); } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人