佛了佛了,这场模拟卡了三个小时,好不容易碰到一道费用流结果根本没时间写
Problem A CFGym 102801A Micro Structure Thread
2 / 3 Problem B CFGym 102801B Team
网络流题目的常见套路,源点和b集合连边,b集合和a集合连边,a集合和c集合连边,这样就能保住必选三个人了,注意a集合在中间要拆点自己和自己的副本连一条流量1费用0的边来现在a只用一次
这种套路洛谷上我就见到至少三个,好可惜啊
``c++
include <bits/stdc++.h>
using namespace std;
const int N = 1e6+7;
int n, m;
string s;
char ch[N];
int tot[N];
string magic(int x) { // 进制转换
string res;
do {
int y = x%16;
res += y < 10 ? y+'0' : y-10+'A';
x /= 16;
} while (x);
reverse(res.begin(), res.end());
return res;
}
string compress() { // 压缩
string res;
for (int i = 0; i < m; ++i) {
if (!tot[i]) continue;
res += ch[i];
if (tot[i] > 1) res += magic(tot[i]);
}
return res;
}
inline bool solve() {
if (!(cin >> s)) return false;
n = s.size();
m = 0;
for (int i = 0, cnt; i < n; ++i) {
if (!i || s[i] != s[i-1]) cnt = 1;
else ++cnt;
if (i == n-1 || s[i] != s[i+1]) {
ch[m] = s[i];
tot[m] = cnt;
++m;
}
}
// 如果长度没法减少,那么del_pos默认为0
int del_pos = 0;
for (int i = 0; i < m; ++i) {
if (tot[i] == 1) {
del_pos = i;
if (i == m-1 || ch[i] > ch[i+1]) break;
}
if (tot[i] == 2 || magic(tot[i]).size() > magic(tot[i]-1).size()) {
del_pos = i;
}
}
--tot[del_pos];
cout << compress() << endl;
return true;
}
signed main() {
ios::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
while (solve()) {}
return 0;
}
``