Все идеи принадлежат MikeMirzayanov.
1385A - Три попарных максимума
Разбор
Tutorial is loading...
Решение
#include <bits/stdc++.h>
using namespace std;
int main() {
#ifdef _DEBUG
freopen("input.txt", "r", stdin);
// freopen("output.txt", "w", stdout);
#endif
int t;
cin >> t;
while (t--) {
vector<int> a(3);
for (auto &it : a) cin >> it;
sort(a.begin(), a.end());
if (a[1] != a[2]) {
cout << "NO" << endl;
} else {
cout << "YES" << endl << a[0] << " " << a[0] << " " << a[2] << endl;
}
}
return 0;
}
1385B - Восстановление перестановки после слияния
Разбор
Tutorial is loading...
Решение
#include <bits/stdc++.h>
using namespace std;
int main() {
#ifdef _DEBUG
freopen("input.txt", "r", stdin);
// freopen("output.txt", "w", stdout);
#endif
int t;
cin >> t;
while (t--) {
int n;
cin >> n;
vector<int> a(2 * n);
for (auto &it : a) cin >> it;
vector<int> used(n);
vector<int> p;
for (int i = 0; i < 2 * n; ++i) {
if (!used[a[i] - 1]) {
used[a[i] - 1] = true;
p.push_back(a[i]);
}
}
for (auto it : p) cout << it << " ";
cout << endl;
}
return 0;
}
Разбор
Tutorial is loading...
Решение
#include <bits/stdc++.h>
using namespace std;
int main() {
#ifdef _DEBUG
freopen("input.txt", "r", stdin);
// freopen("output.txt", "w", stdout);
#endif
int t;
cin >> t;
while (t--) {
int n;
cin >> n;
vector<int> a(n);
for (auto &it : a) cin >> it;
int pos = n - 1;
while (pos > 0 && a[pos - 1] >= a[pos]) --pos;
while (pos > 0 && a[pos - 1] <= a[pos]) --pos;
cout << pos << endl;
}
return 0;
}
Разбор
Tutorial is loading...
Решение
#include <bits/stdc++.h>
using namespace std;
int calc(const string &s, char c) {
if (s.size() == 1) {
return s[0] != c;
}
int mid = s.size() / 2;
int cntl = calc(string(s.begin(), s.begin() + mid), c + 1);
cntl += s.size() / 2 - count(s.begin() + mid, s.end(), c);
int cntr = calc(string(s.begin() + mid, s.end()), c + 1);
cntr += s.size() / 2 - count(s.begin(), s.begin() + mid, c);
return min(cntl, cntr);
}
int main() {
#ifdef _DEBUG
freopen("input.txt", "r", stdin);
// freopen("output.txt", "w", stdout);
#endif
int t;
cin >> t;
while (t--) {
int n;
string s;
cin >> n >> s;
cout << calc(s, 'a') << endl;
}
return 0;
}
Разбор
Tutorial is loading...
Решение
#include <bits/stdc++.h>
using namespace std;
vector<int> ord;
vector<int> used;
vector<vector<int>> g;
void dfs(int v) {
used[v] = 1;
for (auto to : g[v]) {
if (!used[to]) dfs(to);
}
ord.push_back(v);
}
int main() {
#ifdef _DEBUG
freopen("input.txt", "r", stdin);
// freopen("output.txt", "w", stdout);
#endif
int t;
cin >> t;
while (t--) {
int n, m;
cin >> n >> m;
g = vector<vector<int>>(n);
vector<pair<int, int>> edges;
for (int i = 0; i < m; ++i) {
int t, x, y;
cin >> t >> x >> y;
--x, --y;
if (t == 1) {
g[x].push_back(y);
}
edges.push_back({x, y});
}
ord.clear();
used = vector<int>(n);
for (int i = 0; i < n; ++i) {
if (!used[i]) dfs(i);
}
vector<int> pos(n);
reverse(ord.begin(), ord.end());
for (int i = 0; i < n; ++i) {
pos[ord[i]] = i;
}
bool bad = false;
for (int i = 0; i < n; ++i) {
for (auto j : g[i]) {
if (pos[i] > pos[j]) bad = true;
}
}
if (bad) {
cout << "NO" << endl;
} else {
cout << "YES" << endl;
for (auto [x, y] : edges) {
if (pos[x] < pos[y]) {
cout << x + 1 << " " << y + 1 << endl;
} else {
cout << y + 1 << " " << x + 1 << endl;
}
}
}
}
return 0;
}
Разбор
Tutorial is loading...
Решение
#include <bits/stdc++.h>
using namespace std;
int n, k, ans;
vector<set<int>> g;
vector<set<int>> leaves;
struct comp {
bool operator() (int a, int b) const {
if (leaves[a].size() == leaves[b].size()) return a < b;
return leaves[a].size() > leaves[b].size();
}
};
int main() {
#ifdef _DEBUG
freopen("input.txt", "r", stdin);
// freopen("output.txt", "w", stdout);
#endif
int t;
cin >> t;
while (t--) {
cin >> n >> k;
g = leaves = vector<set<int>>(n);
for (int i = 0; i < n - 1; ++i) {
int x, y;
cin >> x >> y;
--x, --y;
g[x].insert(y);
g[y].insert(x);
}
for (int i = 0; i < n; ++i) {
if (g[i].size() == 1) {
leaves[*g[i].begin()].insert(i);
}
}
set<int, comp> st;
for (int i = 0; i < n; ++i) {
st.insert(i);
}
int ans = 0;
while (true) {
int v = *st.begin();
if (int(leaves[v].size()) < k) break;
for (int i = 0; i < k; ++i) {
int leaf = *leaves[v].begin();
g[leaf].erase(v);
g[v].erase(leaf);
st.erase(v);
st.erase(leaf);
leaves[v].erase(leaf);
if (leaves[leaf].count(v)) leaves[leaf].erase(v);
if (g[v].size() == 1) {
int to = *g[v].begin();
st.erase(to);
leaves[to].insert(v);
st.insert(to);
}
st.insert(v);
st.insert(leaf);
}
ans += 1;
}
cout << ans << endl;
}
return 0;
}
Разбор
Tutorial is loading...
Решение
#include <bits/stdc++.h>
using namespace std;
int cnt0, cnt1;
vector<int> col, comp;
vector<vector<pair<int, int>>> g;
void dfs(int v, int c, int cmp) {
col[v] = c;
if (col[v] == 0) ++cnt0;
else ++cnt1;
comp[v] = cmp;
for (auto [to, change] : g[v]) {
if (col[to] == -1) {
dfs(to, c ^ change, cmp);
}
}
}
int main() {
#ifdef _DEBUG
freopen("input.txt", "r", stdin);
// freopen("output.txt", "w", stdout);
#endif
int t;
cin >> t;
while (t--) {
int n;
cin >> n;
vector<vector<int>> a(2, vector<int>(n));
vector<vector<int>> pos(n);
for (int i = 0; i < 2; ++i) {
for (int j = 0; j < n; ++j) {
cin >> a[i][j];
--a[i][j];
pos[a[i][j]].push_back(j);
}
}
bool bad = false;
g = vector<vector<pair<int, int>>>(n);
for (int i = 0; i < n; ++i) {
if (pos[i].size() != 2) {
bad = true;
break;
}
int c1 = pos[i][0], c2 = pos[i][1];
if (c1 == c2) continue;
int r1 = a[0][c1] != i, r2 = a[0][c2] != i;
g[c1].push_back({c2, r1 == r2});
g[c2].push_back({c1, r1 == r2});
}
col = comp = vector<int>(n, -1);
int cnt = 0;
vector<pair<int, int>> colcnt;
int ans = 0;
for (int i = 0; i < n; ++i) {
if (col[i] == -1) {
cnt0 = cnt1 = 0;
dfs(i, 0, cnt);
++cnt;
colcnt.push_back({cnt0, cnt1});
ans += min(cnt0, cnt1);
}
}
for (int i = 0; i < n; ++i) {
for (auto [j, diff] : g[i]) {
if ((col[i] ^ col[j]) != diff) {
bad = true;
}
}
}
if (bad) {
cout << -1 << endl;
} else {
cout << ans << endl;
for (int i = 0; i < n; ++i) {
int changeZero = colcnt[comp[i]].first < colcnt[comp[i]].second;
if (col[i] ^ changeZero) {
cout << i + 1 << " ";
}
}
cout << endl;
}
}
return 0;
}