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;
}
posted @ 2022-08-05 23:11  chenyilei  阅读(32)  评论(0编辑  收藏  举报