2026夏组队训练赛第十四场
B. Brickwork
扫描线,第一行和最后一行必须是整块,且相等剩下的每一行进来的和出去的必须完全一样。
cpp
#include <bits/stdc++.h>
using namespace std;
map<int, vector<tuple<int, int, int>>> mp;
int main() {
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
int n;
cin >> n;
for (int i = 1; i <= n; ++i) {
int x, y, w, h;
cin >> x >> y >> h >> w;
mp[x].emplace_back(y, y + w - 1, 1);
mp[x + h].emplace_back(y, y + w - 1, -1);
}
auto check = [](vector<pair<int, int>> &v) -> vector<pair<int, int>> {
if (v.empty()) return {};
sort(v.begin(), v.end());
vector<pair<int, int>> res = {v[0]};
for (int i = 1; i < v.size(); ++i) {
// cout << v[i].first << ' ' << res.back().second << '\n';
if (v[i].first == res.back().second + 1) res.back().second = v[i].second;
else if (v[i].first > res.back().second + 1) res.emplace_back(v[i]);
else return {{-1, -1}};
}
return res;
};
vector<pair<int, int>> tmp1, tmp2;
vector<pair<int, int>> t = {{-1, -1}};
for (auto it = mp.begin(); it != mp.end(); ++it) {
// cout << "row " << it->first << '\n';
vector<pair<int, int>> v1, v2;
for (auto [l, r, f] : it->second) {
if (f == 1) v1.emplace_back(l, r);
else v2.emplace_back(l, r);
// cout << l << ' ' << r << ' ' << f << '\n';
}
auto p1 = check(v1), p2 = check(v2);
// for (auto [l, r] : p1) cout << "[" << l << ',' << r << "] ";
// cout << '\n';
// for (auto [l, r] : p2) cout << "[" << l << ',' << r << "] ";
// cout << '\n';
if (p1 == t || p2 == t) {
cout << "no\n";
return 0;
}
else if (it == mp.begin()) {
tmp1 = p1;
continue;
}
else if (it == --mp.end()) {
tmp2 = p2;
continue;
}
else if (p1 == p2) continue;
else {
cout << "no\n";
return 0;
}
}
cout << (tmp1 == tmp2 && tmp1.size() == 1 ? "yes\n" : "no\n");
return 0;
}C. Colourful Captcha
cpp
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
char a[11][101];
map<char, int> mp;
void put(int x, int y, int len, int type) {
if (type == 0) {
for (int i = 0; i < len; i ++) a[x][y + i] = 'A';
} else if (type == 1) {
for (int i = 0; i < len; i ++) a[x][y + i] = 'A';
a[x + 1][y] = a[x + 1][y + len - 1] = 'A';
for (int i = 0; i < len; i ++) a[x + 2][y + i] = 'A';
} else {
for (int i = 0; i < len; i ++) a[x][y + i] = 'A';
a[x + 1][y] = a[x + 1][y + len - 1] = 'A';
for (int i = 0; i < len; i ++) a[x + 2][y + i] = 'A';
a[x + 3][y] = a[x + 3][y + len - 1] = 'A';
for (int i = 0; i < len; i ++) a[x + 4][y + i] = 'A';
}
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
//freopen("out.txt", "w", stdout);
for (int i = 1; i <= 10; i ++) {
for (int j = 1; j <= 100; j ++) {
a[i][j] = '.';
}
}
mp['B'] = 2;
string tmp = "ADOPQR";
for (auto c : tmp) mp[c] = 1;
string s1, s2;
cin >> s1 >> s2;
int x = 1, y = 1;
for (auto c : s1) {
put(x, y, size(s2), mp[c]);
y += 11;
}
y = 1;
for (int i = 0; i < size(s1); i ++) {
for (int j = 0; j < size(s2); j ++) {
a[1][y + j] = s2[j];
}
y += 11;
}
for (int i = 1; i <= 10; i ++) {
for (int j = 1; j <= 100; j ++) {
cout << a[i][j];
}
cout << '\n';
}
}D. Depot
背包 dp。
cpp
#pragma GCC optimize("O2")
#include <bits/stdc++.h>
#include <complex>
using namespace std;
#define int long long
#define i64 int64_t
#define db long double
#define pii pair<int, int>
#define tiii tuple<int, int, int>
#define ull unsigned long long
#define vi vector<int>
using i128 = __int128;
#define vpii vector<pii>
#define vvpii vector<vector<pii>>
#define vvi vector<vi>
#define pqpii priority_queue<pii, vector<pii>, greater<pii>>
#define pqi priority_queue<int, vi, greater<int>>
#define f first
#define s second
#define all(x) (x).begin(), (x).end()
#define pb push_back
#define eb emplace_back
#define sz(x) (x).size()
#define mp make_pair
#define endl '\n'
void pr(vector<int> a) {
for (auto i : a)
cout << i << ' ';
cout << '\n';
}
const int mod = 998244353;
const int INF = 1e18;
const int N = 1e6 + 5;
void init() {}
void solve() {
int n, m;
cin >> n >> m;
int s, k;
cin >> s >> k;
vvpii a(n);
for (int i = 0; i < m; i++) {
int it, mi, mo;
cin >> it >> mi >> mo;
a[it].pb({mi,mo});
}
int res=s;
for(int i=1;i<n;i++){
vi dp(res+1,0);
for(int j=res;j>=0;j--){
for(auto [w1,w2]:a[i]){
if(j<w1)continue;
if(j-w1+w2>k)continue;
dp[j-w1]=max(dp[j-w1],min(dp[j]+w2,k-(j-w1)));
}
}
res=dp[0];
// cout<<res<<endl;
}
cout<<res<<endl;
}
signed main() {
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
init();
int t = 1;
// cin>>t;
while (t--) {
solve();
}
return 0;
}E. Enclosure
三分峰值。
cpp
#include <bits/stdc++.h>
#define int long long
using namespace std;
typedef long double LD;
const LD PI = acosl(-1);
signed main() {
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
int T;
cin >> T;
while (T--) {
int m, t;
cin >> m >> t;
int l = 3, r = t / m;
auto calc = [&](int n) -> LD {
return tanl(((LD)n - 2) * PI / (n * 2)) * (t - (LD)n * m) / n * (t - (LD)n * m) / n / 4 * n;
};
while (l + 1000 < r) {
int m1 = (l * 2 + r) / 3, m2 = (l + r * 2) / 3;
LD v1 = calc(m1), v2 = calc(m2);
if (v1 > v2)
r = m2;
else
l = m1;
}
LD res = 0;
// cout << t / m << '\n';
for (int i = l; i <= r; ++i) {
res = max(res, calc(i));
}
cout << fixed << setprecision(10) << res << '\n';
}
return 0;
}F. Fell Walking
枚举最小值,然后不断往后枚举最大值用 dsu 维护可行性。
cpp
#include <bits/stdc++.h>
using namespace std;
const int N = 5010;
vector<int> adj[N];
int h[N], pos[N];
int fa[N];
int getfa(int x) {
return x == fa[x] ? x : fa[x] = getfa(fa[x]);
}
void merge(int x, int y) {
x = getfa(x), y = getfa(y);
if (x != y) fa[y] = x;
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
int n, m;
cin >> n >> m;
for (int i = 1; i <= n; ++i) cin >> h[i];
for (int i = 1; i <= m; ++i) {
int x, y;
cin >> x >> y;
adj[x].emplace_back(y);
adj[y].emplace_back(x);
}
for (int i = 1; i <= n; ++i) pos[i] = i;
sort(pos + 1, pos + n + 1, [&](int x, int y) {
return h[x] < h[y];
});
int res = INT_MAX;
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= n; ++j) fa[j] = j;
for (int j = i; j <= n; ++j) {
for (int y : adj[pos[j]]) {
if (h[y] <= h[pos[j]] && h[y] >= h[pos[i]]) merge(pos[j], y);
}
if (getfa(1) == getfa(2)) {
res = min(res, h[pos[j]] - h[pos[i]]);
break;
}
}
}
cout << res << '\n';
return 0;
}G. Get Good
cpp
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
void solve() {
ll n, a, b, x, y;
cin >> n >> a >> b >> x >> y;
ll need = min(n, x);
ll ans = need * a;
n -= need;
ll T = (x + y);
ll k = n / T;
ll left = n % T;
ll val1 = x * a;
ll val2 = (x + y) * b;
ans += k * max(val1, val2);
ll work = max(0ll, left - y);
val1 = work * a;
val2 = left * b;
ans += max(val1, val2);
cout << ans << '\n';
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
int t;
cin >> t;
while (t --) solve();
}H. Hybrid Search
预处理 dfn 和深度
- 对于第一个直接 bfs,过程中用 dfn 更新答案
- 对于第二个遍历 dfs 序,用主席树维护子树中深度的区间和,查询深度严格小于目标点的和 dfn 小于等于目标点且深度等于目标点的,求和更新答案。
cpp
#include <bits/stdc++.h>
using namespace std;
const int N = 100010;
vector<int> adj[N];
int dep[N], dfn[N], cnt[N], rk[N], t;
struct Node {
int val, ls, rs;
} tr[N * 20];
int rt[N], tot;
void modify(int &u, int v, int l, int r, int p, int d) {
u = ++tot;
tr[u] = tr[v];
if (l == r) tr[u].val += d;
else {
int mid = l + r >> 1;
if (p <= mid) modify(tr[u].ls, tr[v].ls, l, mid, p, d);
else modify(tr[u].rs, tr[v].rs, mid + 1, r, p, d);
tr[u].val = tr[tr[u].ls].val + tr[tr[u].rs].val;
}
}
int query(int u, int v, int l, int r, int ql, int qr) {
if (!u && !v) return 0;
else if (ql <= l && r <= qr) return tr[u].val - tr[v].val;
else {
int mid = l + r >> 1, res = 0;
if (ql <= mid) res += query(tr[u].ls, tr[v].ls, l, mid, ql, qr);
if (qr > mid) res += query(tr[u].rs, tr[v].rs, mid + 1, r, ql, qr);
return res;
}
}
void dfs(int x, int fa) {
dfn[x] = ++t;
rk[t] = x;
cnt[x] = 1;
for (int y : adj[x]) {
if (y == fa) continue;
dep[y] = dep[x] + 1;
dfs(y, x);
cnt[x] += cnt[y];
}
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
int n, s;
cin >> n >> s;
for (int i = 1; i < n; ++i) {
int x, y;
cin >> x >> y;
adj[x].emplace_back(y);
adj[y].emplace_back(x);
}
dep[1] = 1;
dfs(1, 0);
queue<pair<int, int>> q;
q.emplace(1, 0);
t = 0;
int res = n;
while (!q.empty()) {
auto [x, fa] = q.front();
q.pop();
t++;
if (dfn[x] <= dfn[s] && dfn[s] <= dfn[x] + cnt[x] - 1) {
res = min(res, t + dfn[s] - dfn[x]);
}
for (int y : adj[x]) {
if (y == fa) continue;
q.emplace(y, x);
}
}
cout << res << '\n';
res = n;
for (int i = 1; i <= n; ++i) {
modify(rt[i], rt[i - 1], 1, n, dep[rk[i]], 1);
}
auto qsum = [&](int l, int r, int d1, int d2) -> int {
return query(rt[r], rt[l], 1, n, d1, d2);
};
for (int i = 1; i <= n; ++i) {
int x = rk[i];
if (dfn[x] <= dfn[s] && dfn[s] <= dfn[x] + cnt[x] - 1) {
res = min(res, i + qsum(i, i + cnt[x] - 1, 1, dep[s] - 1) + qsum(i, dfn[s], dep[s], dep[s]));
}
}
cout << res << '\n';
return 0;
}I. Itsy Bits
cpp
#include <bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
long long x;
cin >> x;
for (int i = 0; i < 10; ++i) {
if ((__int128_t)(1) << (1LL << i) > x) {
if (i == 0) cout << "1 bit\n";
else cout << (1LL << i) << " bits\n";
return 0;
}
}
return 0;
}J. Joust Sort
拓扑排序。
cpp
#include <bits/stdc++.h>
using namespace std;
vector<int> adj[128];
int deg[128], cnt[128];
int main() {
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
int n;
cin >> n;
for (int i = 0; i < n; ++i) {
char a, b, c;
cin >> a >> b >> c;
if (b == '>') {
adj[c].emplace_back(a);
deg[a]++;
}
else {
adj[a].emplace_back(c);
deg[c]++;
}
}
string s;
cin >> s;
for (char c : s) cnt[c]++;
queue<int> q;
for (int i = 0; i < 128; ++i) if (!deg[i]) q.emplace(i);
string t;
while (!q.empty()) {
int x = q.front();
q.pop();
for (int i = 0; i < cnt[x]; ++i) t += x;
for (int y : adj[x]) {
if (--deg[y] == 0) q.emplace(y);
}
}
if (t.length() == s.length()) cout << t << '\n';
else cout << "IMPOSSIBLE\n";
return 0;
}L. Last Orders
分层图最短路。
cpp
#pragma GCC optimize("O2")
#include <bits/stdc++.h>
#include <complex>
using namespace std;
#define int long long
#define i64 int64_t
#define db long double
#define pii pair<int, int>
#define tiii tuple<int, int, int>
#define ull unsigned long long
#define vi vector<int>
using i128 = __int128;
#define vpii vector<pii>
#define vvpii vector<vector<pii>>
#define vvi vector<vi>
#define pqpii priority_queue<pii, vector<pii>, greater<pii>>
#define pqi priority_queue<int, vi, greater<int>>
#define f first
#define s second
#define all(x) (x).begin(), (x).end()
#define pb push_back
#define eb emplace_back
#define sz(x) (x).size()
#define mp make_pair
#define endl '\n'
void pr(vector<int> a) {
for (auto i : a)
cout << i << ' ';
cout << '\n';
}
const int mod = 998244353;
const int INF = 1e10;
const int N = 1e6 + 5;
void init() {}
void solve() {
int n;
cin>>n;
vi a(n);
for(int i=0;i<n;i++)cin>>a[i];
int m;
cin>>m;
vi t(m);
for(int i=0;i<m;i++)cin>>t[i];
vvi dis(m,vi(m,INF));
for(int i=0;i<m;i++)dis[i][i]=0;
int q;
cin>>q;
for(int i=0;i<q;i++){
int u,v,w;
cin>>u>>v>>w;
u--,v--;
dis[u][v]=w;
dis[v][u]=w;
}
for(int k=0;k<m;k++){
for(int i=0;i<m;i++){
for(int j=0;j<m;j++){
dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);
}
}
}
// for(int i=0;i<m;i++){
// for(int j=0;j<m;j++){
// cout<<dis[i][j]<<" ";
// }
// cout<<"\n";
// }
vvi dp(n+1,vi(m,INF));
dp[0][0]=0;
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
if(dp[i][j]>t[j])continue;
for(int k=0;k<m;k++){
if(k==j&&i!=0)continue;
dp[i+1][k]=min(dp[i+1][k],dp[i][j]+a[i]+dis[j][k]);
}
}
}
int ans=0;
for(int i=0;i<=n;i++){
for(int j=0;j<m;j++){
// cout<<dp[i][j]<<" ";
if(dp[i][j]<=t[j])ans=i;
}
// cout<<"\n";
}
cout<<ans<<endl;
}
signed main() {
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
init();
int t = 1;
// cin>>t;
while (t--) {
solve();
}
return 0;
}M. Motorway Stops
cpp
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
int n;
cin >> n;
vector<int> a(n + 1);
for (int i = 1; i <= n; i ++) cin >> a[i];
int ans = 0;
for (int i = 2; i <= n; i ++) ans = max(ans, a[i] - a[i - 1]);
int mn = 1e9;
for (int i = 2; i < n; i ++) {
mn = min(mn, a[i + 1] - a[i - 1]);
}
cout << max(ans, mn);
}其他没做的题
- Arboreal Challenge
- Klaus