2022“杭电杯”中国大学生算法设计超级联赛(3)
Cyber Language
直接输出
#include <bits/stdc++.h>
using namespace std;
char s[100];
int main() {
// freopen("a.in", "r", stdin);
int n;
scanf("%d\n", &n);
while (n--) {
gets(s);
putchar(s[0] + 'A' - 'a');
for (int i = 1; s[i]; ++i)
if (s[i - 1] == ' ')
putchar(s[i] + 'A' - 'a');
puts("");
}
return 0;
}
Package Delivery
有\(n\)个包裹,每个包裹在\([l_i,r_i]\)时间内存在,一次只能带至多\(k\)个包裹回家,问最少几次。(一天可以去好几次)
按\(r_i\)排序,找到时间最早的没拿满\(k\)个的挤进去,没找到就在\(r_i\)天新去一次。
#include <bits/stdc++.h>
using namespace std;
struct Info {
int l, r;
bool operator <(const Info &rhs) const {
return r < rhs.r;
}
};
Info a[100005];
map<int, int> s;
int n, k;
int main() {
int T; scanf("%d", &T);
while (T--) {
scanf("%d%d", &n, &k);
for (int i = 1; i <= n; ++i) scanf("%d%d", &a[i].l, &a[i].r);
if (k == 1) printf("%d\n", n);
else {
sort(a + 1, a + n + 1);
s.clear();
int ans = 0;
for (int i = 1; i <= n; ++i) {
auto x = s.lower_bound(a[i].l);
if (x != s.end()) {
++x->second;
if (x->second == k) s.erase(x);
} else {
++ans;
s[a[i].r] = 1;
}
}
printf("%d\n", ans);
}
}
return 0;
}
Taxi
有\(n\)个镇,有参数\((x_i,y_i,w_i)\),有\(q\)个询问,每次给定一个\((x',y')\)
求上式的最大值\((k=1..n)\)
可以发现\(max\{min\{|x'-x_k|+|y'-y_k|,w_k\}\}\)
\(=max\{min\{x'-x_k+y'-y_k,w_k\},min\{x'-x_k-y'+y_k,w_k\},min\{-x'+x_k+y'-y_k,w_k\},min\{-x'+x_k-y'+y_k,w_k\}\}\)
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
struct Info {
ll val, l, r;
bool operator <(const Info &rhs) const {
return val < rhs.val;
}
};
vector<Info> A, B, C, D;
int n, q;
pair<ll, ll> get(const vector<Info> &a, ll x) {
int l = 0, r = n;
while (l < r) {
int mid = l + 1 + r >> 1;
if (a[mid].val <= x) l = mid;
else r = mid - 1;
}
pair<ll, ll> ret(-1e18, -1e18);
if (l != 0) ret.first = a[l].l;
if (l != n) ret.second = a[l + 1].r;
return ret;
}
int main() {
int T; scanf("%d", &T);
while (T--) {
scanf("%d%d", &n, &q);
A.resize(1);
B.resize(1);
C.resize(1);
D.resize(1);
for (int i = 1; i <= n; ++i) {
ll x, y, w; scanf("%lld%lld%lld", &x, &y, &w);
A.push_back((Info){x + y - w, x + y, w});
B.push_back((Info){x - y - w, x - y, w});
C.push_back((Info){-x + y - w, -x + y, w});
D.push_back((Info){-x - y - w, -x - y, w});
}
sort(A.begin() + 1, A.end());
sort(B.begin() + 1, B.end());
sort(C.begin() + 1, C.end());
sort(D.begin() + 1, D.end());
for (int i = 2; i <= n; ++i) {
A[i].l = max(A[i].l, A[i - 1].l);
B[i].l = max(B[i].l, B[i - 1].l);
C[i].l = max(C[i].l, C[i - 1].l);
D[i].l = max(D[i].l, D[i - 1].l);
}
for (int i = n - 1; i >= 1; --i) {
A[i].r = max(A[i].r, A[i + 1].r);
B[i].r = max(B[i].r, B[i + 1].r);
C[i].r = max(C[i].r, C[i + 1].r);
D[i].r = max(D[i].r, D[i + 1].r);
}
while (q--) {
ll x, y, ans = -1e18; scanf("%lld%lld", &x, &y);
pair<ll, ll> ret = get(A, x + y);
ans = max(ans, ret.first - x - y);
ans = max(ans, ret.second);
ret = get(B, x - y);
ans = max(ans, ret.first - x + y);
ans = max(ans, ret.second);
ret = get(C, -x + y);
ans = max(ans, ret.first + x - y);
ans = max(ans, ret.second);
ret = get(D, -x - y);
ans = max(ans, ret.first + x + y);
ans = max(ans, ret.second);
printf("%lld\n", ans);
}
}
return 0;
}
Two Permutations
给n的两个排列P、Q,和一个长2n的S,每次可以将P、Q任意一个的最左边的元素弹出加入A的末尾,问使A=S的方案数。
不会正解。随便写了个搜索,先用了dfs+map,后来用bfs+hash改了改模数勉强过了
#include <bits/stdc++.h>
using namespace std;
int gi() {
int x = 0; char c = getchar();
while (c < '0' || c > '9') c = getchar();
while (c >= '0' && c <= '9') x = (x << 3) + (x << 1) + c - 48, c = getchar();
return x;
}
struct Hash {
static const int hash = 49999991;
long long state[5000005];
int fir[hash], cnt, nxt[5000005], val[5000005];
void clear() {
for (int i = 1; i <= cnt; ++i) {
fir[state[i] % hash] = 0;
nxt[i] = 0;
}
cnt = 0;
}
int get(long long x) {
int key = x % hash;
for (int i = fir[key]; i; i = nxt[i])
if (state[i] == x)
return i;
nxt[++cnt] = fir[key];
fir[key] = cnt;
state[cnt] = x;
val[cnt] = 0;
return cnt;
}
int &operator [](long long x) { return val[get(x)]; }
} ha;
const int mod = 998244353;
queue<int> p, q;
int n, a[300005], b[300005], c[600005];
int main() {
// freopen("a.in", "r", stdin);
int T = gi();
while (T--) {
n = gi();
for (int i = 1; i <= n; ++i) a[i] = gi();
for (int i = 1; i <= n; ++i) b[i] = gi();
for (int i = 1; i <= n << 1; ++i) c[i] = gi();
ha.clear();
p.push(0);
q.push(0);
ha[0] = 1;
while (p.size()) {
int x = p.front(), y = q.front();
long long tmp = x * 300003ll + y;
int s = ha[tmp];
p.pop(), q.pop();
if (x < n && c[x + y + 1] == a[x + 1]) {
int &pt = ha[tmp + 300003];
if (pt) {
pt += s;
if (pt >= mod) pt -= mod;
} else {
pt = s;
p.push(x + 1);
q.push(y);
}
}
if (y < n && c[x + y + 1] == b[y + 1]) {
int &pt = ha[tmp + 1];
if (pt) {
pt += s;
if (pt >= mod) pt -= mod;
} else {
pt = s;
p.push(x);
q.push(y + 1);
}
}
}
printf("%d\n", ha[300003ll * n + n]);
}
return 0;
}