重庆市第十三届程序设计大赛
F、H
略
L
每次维护栈顶的n个元素,因为不会pop到后面的元素
C
稍微有点意思的一个构造,有很多不同的通过方案。感觉纯纯奇思妙想题。赛时队友秒了。
赛后因为不会妙妙构造,写了很暴力的构式实现(\(O(nlogn)\))草过去了
#include <bits/stdc++.h>
using namespace std;
using LL = long long;
// #define int long long
const int N = 2e5 + 7, mod = 1e9 + 7;
int read() {
int res = 0, f = 1;
char c = getchar();
while(c < '0' || c > '9') {
if (c == '-') f = -1;
c = getchar();
}
while(c >= '0' && c <= '9') {
res = res * 10 + c - '0';
c = getchar();
}
return res * f;
}
int add(int a, int b) {
return (a + b) % mod ;
}
int mul(int a, int b) {
return 1ll * a * b % mod;
}
int sub(int a, int b) {
return (a+mod-b)%mod;
}
int qpow(int x, int y) {
int res = 1;
while(y) {
if (y & 1) res = mul(res, x);
x = mul(x, x);
y >>= 1;
}
return res;
}
int vis[1015][1015];
void solve() {
int n;
cin >> n;
int nw = 1;
int num = 0;
for (int i = 1; i <= n; i++) {
vis[i][0] = 1;
vis[i][i] = 1;
}
set<int>q;
for (int i = 1; i <= n; i++) q.insert(i);
for (int i = 1; i <= n; i++) {
nw = *q.begin();
for (int j = 1; j <= n; j++) {
if (num == n) {
cout << n << ' ';
continue;
}
cout << nw << ' ';
if (j == n) break;
int b, lst = nw;
b = vis[nw][0];
while(b <= n && vis[nw][b]) b++, vis[nw][0]++;
if(!q.empty() && b > n){
q.erase(nw);
num++;
b = *q.begin();
}
if (b > n) continue;
nw = b;
vis[lst][b] = 1;
vis[b][lst] = 1;
}
cout << endl;
}
for (int i = 0; i <= n; i++) for (int j = 0; j <= n; j++) vis[i][j] = 0;
}
signed main(){
int t = 1;
cin >> t;
while(t--){
solve();
}
}
B
赛时队友贪心草过去了但是严禁证明是网络流的最大流最小割。
只要求最小割就可以了。
实现上是map离散化+差分(为什么用map离散化是个谜)
#include <bits/stdc++.h>
using namespace std;
using LL = long long;
// #define int long long
const int N = 8e5 + 10, mod = 1e9 + 7;
int read() {
int res = 0, f = 1;
char c = getchar();
while(c < '0' || c > '9') {
if (c == '-') f = -1;
c = getchar();
}
while(c >= '0' && c <= '9') {
res = res * 10 + c - '0';
c = getchar();
}
return res * f;
}
int add(int a, int b) {
return (a + b) % mod ;
}
int mul(int a, int b) {
return 1ll * a * b % mod;
}
int sub(int a, int b) {
return (a+mod-b)%mod;
}
int qpow(int x, int y) {
int res = 1;
while(y) {
if (y & 1) res = mul(res, x);
x = mul(x, x);
y >>= 1;
}
return res;
}
struct Node {
int l, r, c;
}a[N];
LL b[N];
bool cmp(const Node &x, const Node &y) {
return x.l < y.l;
}
void solve() {
int n, m;
cin >> n >> m;
LL ans = 0x3f3f3f3f3f3f3f, sum = 0;
map<int, int>mp;
for (int i = 1; i <=m; i++) {
cin >> a[i].l >> a[i].r >> a[i].c;
mp[a[i].l] = a[i].l;
mp[a[i].r] = a[i].r;
}
int tot = 0, mx = 0, mn = 0;
for (auto &i : mp) {
if (i.first == 1) mn = 1;
tot++;
i.second = tot;
if (i.first == n) mx = tot;
// tot++;
}
sort(a + 1, a + m + 1, cmp);
for (int i = 1; i <= m; i++) {
a[i].l = mp[a[i].l];
a[i].r = mp[a[i].r];
b[a[i].l] += a[i].c;
b[a[i].r] -= a[i].c;
}
for (int i = 1; i <= mx - 1; i++) {
sum += b[i];
ans = min(sum, ans);
b[i] = 0;
}
for (int i = mx; i <= tot; i++) b[i] = 0;
if (mx && mn) cout << ans << endl;
else cout << 0 << endl;
}
signed main(){
int t = 1;
cin >> t;
while(t--){
solve();
}
}
J
白色的点会构成一个连通块(在树中间)
所以就统计至少中间要有多少白点,这个不好统计所以去统计不需要涂的点
D
以下待补

浙公网安备 33010602011771号