1 条题解
-
0
C++ 入门之递归算法。这个让一批批人上场的过程很像染色。一种颜色的刷子只能用一次。
考虑如何完成 的合法染色。
- 如果 。先对整个区间染色成 。然后递归处理。令 为 内颜色 的出现位置。则递归处理 。
- 否则,令 下一次出现的位置为 ,则递归处理 和 。
考虑怎样判断无解。当我们想给区间 染色 时,如果区间外还存在这种颜色,即无解。
#include <bits/stdc++.h> using namespace std; const int N = 3e5 + 10; int n, m, a[N], cnt; vector<int> vec[N]; struct Node { int l, r, w; }p[N]; vector<int> res; int mn[N], mx[N]; bool solve(int l, int r) { if (l > r) return true; if (p[l].w == p[r].w) { res.push_back(p[l].w); if (vec[p[l].w][0] < l || vec[p[l].w].back() > r) return false; for (int i = 0; i + 1 < vec[p[l].w].size(); ++ i ) { if (!solve(vec[p[l].w][i] + 1, vec[p[l].w][i + 1] - 1)) return false; } } else { if (!solve(l, vec[p[l].w].back())) return false; if (!solve(vec[p[l].w].back() + 1, r)) return false; } return true; } int st[N][20]; int query(int l, int r) { int k = log2(r - l + 1); return max(st[l][k], st[r - (1 << k) + 1][k]); } void solve() { cin >> n >> m; memset(mn, 0x3f, sizeof mn); memset(mx, -0x3f, sizeof mx); for (int i = 1; i <= n; ++ i ) { cin >> a[i]; if (a[i] == a[i - 1]) { p[cnt].r ++ ; } else { p[ ++ cnt] = {i, i, a[i]}; } mx[a[i]] = max(mx[a[i]], i); mn[a[i]] = min(mn[a[i]], i); } for (int i = 1; i <= cnt; ++ i ) { vec[p[i].w].push_back(i); } if (!solve(1, cnt)) { cout << -1; return; } cout << res.size() << '\n'; for (int v : res) cout << v << ' ' << mn[v] << ' ' << mx[v] << '\n'; } signed main() { ios::sync_with_stdio(0); cin.tie(0), cout.tie(0); int T = 1; #ifdef tests cin >> T; #endif while (T -- ) solve(); return 0; }
- 1
信息
- ID
- 2345
- 时间
- 2000ms
- 内存
- 512MiB
- 难度
- 10
- 标签
- 递交数
- 10
- 已通过
- 2
- 上传者