文章目录
- CF 449B Jzzhu and Cities
- CF 1945E Binary Search
- CF 1945F Kirill and Mushrooms
- CF 1945G Cook and Porridge
- CF 1349B Orac and Medians
CF 449B Jzzhu and Cities
题目链接
首先跑dijkstra,记录下每个点最短路的入度,然后遍历每一条铁路,如果最短路小于铁路长度,这个铁路就可以删掉,如果最短路等于铁路长度并且最短路入度大于1,说明还有其他路径可以到这个点,就把入度减一并且把这条铁路删掉
这一题的收获是学会了计算到达每个点的最短路径有多少条的方式,就是在更新最短路的时候同时更新最短路入度
#include <bits/stdc++.h>using namespace std;#define int long long
using i64 = long long;typedef pair<int, int> PII;
typedef pair<int, char> PIC;
typedef pair<double, double> PDD;
typedef pair<int, PII> PIII;
typedef pair<int, pair<int, bool>> PIIB;const int N = 1e5 + 10;
const int mod = 1e9 + 7;
const int maxn = 1e6 + 10;
const int mod1 = 954169327;
const int mod2 = 906097321;
const int INF = 0x3f3f3f3f3f3f3f3f;void solve()
{int n, m, k;cin >> n >> m >> k;vector<vector<PII>> g(n + 1);vector<int> ind(n + 1);vector<PII> rot(k);for (int i = 0; i < m; i ++ ){int u, v, x;cin >> u >> v >> x;g[u].push_back({v, x});g[v].push_back({u, x});}for (int i = 0; i < k; i ++ ){int u, x;cin >> u >> x;g[1].push_back({u, x});g[u].push_back({1, x});rot[i] = {u, x};}vector<int> dist(n + 1, INF);vector<bool> st(n + 1, false);priority_queue<PII, vector<PII>, greater<PII>> q;q.push({0, 1});dist[1] = 0;while (q.size()){auto t = q.top();q.pop();int ver = t.second, dd = t.first;if (st[ver]) continue;st[ver] = true;for (int i = 0; i < g[ver].size(); i ++ ){int j = g[ver][i].first;if (dist[j] > dist[ver] + g[ver][i].second){dist[j] = dist[ver] + g[ver][i].second;ind[j] = 1;q.push({dist[j], j});}else if (dist[j] == dist[ver] + g[ver][i].second){ind[j] ++ ;q.push({dist[j], j});}}} int ans = 0;for (auto t : rot){if (dist[t.first] < t.second) ans ++ ;else if (dist[t.first] == t.second && ind[t.first] > 1){ind[t.first] -- ;ans ++ ;}}cout << ans << '\n';
}signed main()
{ios::sync_with_stdio(false);cin.tie(0), cout.tie(0);int t = 1;// cin >> t;while (t--){solve();}
}
CF 1945E Binary Search
题目链接
这题原来只需要按二分步骤做,最后交换x的位置和l的位置就可以了,白瞎昨天写了一个小时
#include <bits/stdc++.h>using namespace std;#define int long long
using i64 = long long;typedef pair<int, int> PII;
typedef pair<int, char> PIC;
typedef pair<double, double> PDD;
typedef pair<int, PII> PIII;
typedef pair<int, pair<int, bool>> PIIB;const int N = 1e5 + 10;
const int mod = 1e9 + 7;
const int maxn = 1e6 + 10;
const int mod1 = 954169327;
const int mod2 = 906097321;
const int INF = 0x3f3f3f3f3f3f3f3f;void solve()
{int n, x;cin >> n >> x;vector<int> a(n + 1);int pos;map<int, int> mp;set<int> st;for (int i = 1; i <= n; i ++ ){cin >> a[i];if (a[i] == x) pos = i;mp[a[i]] = i;if (a[i] < x) st.insert(i);}int l = 1, r = n + 1;vector<PII> ans;bool flag = false;while (l < r - 1){int mid = l + r >> 1;st.erase(a[mid]);if (a[mid] > x) r = mid;else if (a[mid] <= x){if (a[mid] == x) flag = true;l = mid;}}if (flag){for (auto t : st){int tmp1 = mp[x], tmp2 = t;ans.push_back({tmp1, tmp2});swap(a[tmp1], a[tmp2]);swap(mp[x], t);break;}}if (l != mp[x]) ans.push_back({mp[x], l});cout << ans.size() << '\n';for (auto t : ans) cout << t.first << ' ' << t.second << '\n';
}signed main()
{ios::sync_with_stdio(false);cin.tie(0), cout.tie(0);int t = 1;cin >> t;while (t--){solve();}
}
CF 1945F Kirill and Mushrooms
题目链接
比想象的简单,题目意思又理解错
枚举选择了多少个蘑菇
根据贪心的思想,选择蘑菇的大小一定是从大到小的,所以把所有蘑菇放到优先队列里,每次判断队头能不能选,不能选就跳过,能选就选择,并且每次判断之前,先要把p[i - 1]
划到不能选的区域,如果之前已经选过了,需要删掉它
#include <bits/stdc++.h>using namespace std;#define int long long
using i64 = long long;typedef pair<int, int> PII;
typedef pair<int, char> PIC;
typedef pair<double, double> PDD;
typedef pair<int, PII> PIII;
typedef pair<int, pair<int, bool>> PIIB;const int N = 1e5 + 10;
const int mod = 1e9 + 7;
const int maxn = 1e6 + 10;
const int mod1 = 954169327;
const int mod2 = 906097321;
const int INF = 0x3f3f3f3f3f3f3f3f;void solve()
{int n;cin >> n;vector<int> a(n + 1), p(n + 1);for (int i = 1; i <= n; i ++ ) cin >> a[i];for (int i = 1; i <= n; i ++ ) cin >> p[i];priority_queue<PII> q;for (int i = 1; i <= n; i ++ ) q.push({a[i], i});vector<bool> slt(n + 1), ns(n + 1);int cnt = 0, minn = INF, ans = 0, anscnt;for (int i = 1; i <= n && q.size(); i ++ ){if (i != 0){if (slt[p[i - 1]]){slt[p[i - 1]] = false;cnt -- ;}ns[p[i - 1]] = true;}while (cnt != i && q.size()){auto t = q.top();q.pop();if (ns[t.second]) continue;slt[t.second] = true;minn = min(minn, t.first);cnt ++ ;}if (cnt == i){if (minn * cnt > ans){ans = minn * cnt;anscnt = cnt; }}}cout << ans << ' ' << anscnt << '\n';
}signed main()
{ios::sync_with_stdio(false);cin.tie(0), cout.tie(0);int t = 1;cin >> t;while (t--){solve();}
}
CF 1945G Cook and Porridge
题目链接
有点trick的模拟
因为要让所有人都吃上饭,所以我们只要记录一个cur为没有吃上饭的第一个人就可以
我们怎么看他有没有被插队呢,我们用优先队列维护已经吃过饭的人,如果队头的人的优先级比cur以及cur之后所有还没吃饭的人的优先级低,那他就没法插队到cur前面,否则就是队头的人打饭(所以维护一下每个点的后缀最大值)
#include <bits/stdc++.h>using namespace std;#define int long long
using i64 = long long;typedef pair<int, int> PII;
typedef pair<int, char> PIC;
typedef pair<double, double> PDD;
typedef pair<int, PII> PIII;
typedef pair<int, pair<int, bool>> PIIB;const int N = 1e5 + 10;
const int mod = 1e9 + 7;
const int maxn = 1e6 + 10;
const int mod1 = 954169327;
const int mod2 = 906097321;
const int INF = 0x3f3f3f3f3f3f3f3f;void solve()
{int n, d;cin >> n >> d;vector<int> k(n + 1), s(n + 1);for (int i = 1; i <= n; i ++ ) cin >> k[i] >> s[i];vector<int> suf(n + 2);for (int i = n; i >= 1; i -- ) suf[i] = max(suf[i + 1], k[i]);priority_queue<array<int, 4>> q;vector<vector<int>> pos(d + 1);int cur = 1; // 第一个还没有吃上饭的for (int i = 0; i < d; i ++ ){if (!q.empty() && q.top()[0] > suf[cur]) // 被插队{auto [k, t, s, idx] = q.top();q.pop();s = -s;if (i + s <= d) pos[i + s].push_back(idx);}else // 没被插队{if (i + s[cur] <= d) pos[i + s[cur]].push_back(cur);cur ++ ;}if (cur == n + 1){cout << i + 1 << '\n';return;}for (auto t : pos[i]) q.push({k[t], -i, -s[t], t});}cout << -1 << '\n';
}signed main()
{ios::sync_with_stdio(false);cin.tie(0), cout.tie(0);int t = 1;cin >> t;while (t--){solve();}
}
CF 1349B Orac and Medians
题目链接
很蠢的贪心,没想出来想爆锤自己
想到了如果k旁边的一个数大于k,那就可以只选这两个数把另一个数也变成k
所以如果连续的三个数有两个都大于等于k就可以完成
长度为1/2的时候要特判一下
#include <bits/stdc++.h>using namespace std;#define int long long
using i64 = long long;typedef pair<int, int> PII;
typedef pair<int, char> PIC;
typedef pair<double, double> PDD;
typedef pair<int, PII> PIII;
typedef pair<int, pair<int, bool>> PIIB;const int N = 1e5 + 10;
const int mod = 1e9 + 7;
const int maxn = 1e6 + 10;
const int mod1 = 954169327;
const int mod2 = 906097321;
const int INF = 0x3f3f3f3f3f3f3f3f;void solve()
{int n, k;cin >> n >> k;vector<int> a(n);bool flag = false;for (int i = 0; i < n; i ++ ){cin >> a[i];if (a[i] == k) flag = true;}if (!flag){cout << "no\n";return;}if (n == 1){cout << "yes\n";return;}if (n == 2){if (a[0] < k || a[1] < k) cout << "no\n";else cout << "yes\n";return;}int x1 = a[0], x2 = a[1], x3 = a[2], cnt = 0;if (x1 >= k) cnt ++ ;if (x2 >= k) cnt ++ ;if (x3 >= k) cnt ++ ;if (cnt >= 2) flag = false;for (int i = 3; i < n; i ++ ){if (x1 >= k) cnt -- ;x1 = x2, x2 = x3;x3 = a[i];if (x3 >= k) cnt ++ ;if (cnt >= 2) flag = false;}if (flag) cout << "no\n";else cout << "yes\n";
}signed main()
{ios::sync_with_stdio(false);cin.tie(0), cout.tie(0);int t = 1;cin >> t;while (t--){solve();}
}