补题链接:Here
A - Rock-paper-scissors
石头剪刀布,两方是一样的则输出该值,否则输出该值
int s[4] = {0, 1, 2};void solve() {int x, y;cin >> x >> y;if (x == y) cout << x;else {for (int i = 0; i < 3; i++)if (s[i] != x && s[i] != y)cout << s[i];}}
B - Nuts
坚果数超过 个便累加(x-10)
void solve() {int n;cin >> n;int cnt = 0;for (int i = 0, x; i < n; ++i) {cin >> x;if (x > 10)cnt += (x - 10);}cout << cnt;}
C - Tour
个城市,
条单向道路,请问在以每个城市为起点能有多少个终点(本身也算
,DFS 在图上搜索即可
const int N = 2e3 + 10;vector<int>e[N];bool vis[N];void dfs(int u) {if (vis[u])return ;vis[u] = true;for (int v : e[u])dfs(v);}void solve() {int n, m; cin >> n >> m;while (m--) {int a, b; cin >> a >> b;e[a].push_back(b);}int ans = 0;for (int i = 1; i <= n; ++i) {memset(vis, false, sizeof(vis));dfs(i);for (int j = 1; j <= n; ++j)if (vis[j])ans++;}cout << ans;}
D - Cooking
两个微波炉, 道菜,每个菜需要
分钟加热,请问最少需要多少时间才能把所有菜都加热完毕
烤箱的使用顺序无关紧要;只有为每道菜指定一个烤箱才是必要的。
考虑到根据要分配的两个烤箱中的哪一个将菜分为两组,该问题等价于“将N个菜分为两组,使烹调菜所需的最大次数之和最小化。”设为 。我们可以假设第一个烤箱的占用时间不少于第二个烤箱的占用时间(如果不是,我们可以交换这两个烤箱)。然后,第一烤箱的使用持续时间至少为
。由于我们想在这个约束条件下尽可能减少使用第一台烤箱的时间,所以问题归结为“
的子集的最小和大于或等于
是多少?”如果我们能为每个x回答“
的子集是否存在,这只不过是一个子集和问题,所以它可以在
#card=math&code=%5Cmathcal%7BO%7D%28N%5Csum_iT_i%29&id=ullYy) 的总和中找到∑ 具有以下布尔值的DP
bitset<100004>f;void solve() {int n; cin >> n;int cnt = 0;f[0] = 1;for (int i = 0, x; i < n; ++i) {cin >> x;f |= f << x; cnt += x;}int ans = 1e9;for (int i = 0; i < 1e5; ++i)if (f[i])ans = min(ans, max(i, cnt - i));cout << ans;}
E - Rush Hour 2
AtCoder王国有 个城市和
条双向道路
假设在 时刻经过了第
条道路,则通过的时间为
现在请问最短的时间是多少,Takahashi 可以从城市 到达城市
,如果到达不了则输出
利用优先队列跑 BFS,同时用 tuple 元组存储数据 (记得开启 C++17 来保证 tuple 可通过编译)
#define inf 9223372036854775807LL#define N 100005using ll = long long;using Edge = tuple<int, int, int>;using pli = pair<ll, int>;vector<Edge> e[N];ll dist[N];void solve() {int n, m;cin >> n >> m;while (m--) {int a, b, c, d;cin >> a >> b >> c >> d;if (--a == --b)continue;e[a].emplace_back(b, c, d);e[b].emplace_back(a, c, d);}dist[0] = 0LL;for (int i = 1; i < n; i++) dist[i] = inf;priority_queue<pli, vector<pli>, greater<pli>>q;q.emplace(0, 0);while (!q.empty()) {auto [t, u] = q.top();q.pop();if (dist[u] != t)continue;for (auto [v, c, d] : e[u]) {ll t2 = sqrt((long double) d) - 0.5;if (t2 < t) t2 = t;t2 += ll(c) + ll(d) / (t2 + 1ll);if (t2 < dist[v])q.emplace(dist[v] = t2, v);}}cout << (dist[n - 1] == inf ? -1 : dist[n - 1]) << endl;}
