当前位置: 首页 > news >正文

2024南京icpc区域赛详解与难点解释

2024南京icpc详解与难点解释

  • E Left Shifting 3
  • J Social Media
  • K Strips
  • M Ordainer of Inexorable Judgment
  • B Birthday Gift
  • 二叉树

练习地址

本文参考

E Left Shifting 3

签到,最多从前往后移动6位,暴力遍历计算每次的‘nanjing’数量,不需要kmp匹配也可以ac。

#include<bits/stdc++.h>
#define int long long
using namespace std;
void solve() {int n, k;cin >> n >> k;string s;cin >> s;if (s.size() < 7) {cout << 0 << '\n';return;}int res = 0;int cnt = min(6ll, k);for (int i = 0; i <= cnt; i++) {int ans = 0;string s1 = s.substr(0,i);string t = s + s1;for (int j = i; j + 7 <= t.size(); j++) {if (t.substr(j, 7) == "nanjing") {ans ++;}}res = max(res, ans);}cout << res << '\n';
}
signed main() {ios_base::sync_with_stdio(false),cin.tie(0),cout.tie(0);int T;cin >> T;while (T --) {solve();}return 0;
}

J Social Media

类似微信朋友圈的规则。
有两种情况需要分开考虑
1.要添加的这两个好友有互相间评论过。
不一定是能增加最多的,只是在互相评论的两位中最多。

for (auto [e, w] : edge) {
  auto [x, y] = e;
  ans = max(ans, deg[x] + deg[y] + w);
}

2.要添加的这两个好友没有互相间评论过。
不知到最多的两个有没有评论过,不重要,只需与互相评论过的且增加评论最多作比较。

ans = max(ans, deg[0] + deg[1]);

#include <bits/stdc++.h>
using namespace std;int main() {ios::sync_with_stdio(false),cin.tie(nullptr), cout.tie(nullptr);int t;cin >> t;while (t--) {int n, m, k;cin >> k >> m >> n;vector<int> good(n);while (k--) {int x;cin >> x;x--;good[x] = 1;}map<pair<int, int>, int> edge;vector<int> deg(n);int sum = 0;while (m--) {int x, y;cin >> x >> y;x--, y--;if (x > y) swap(x, y);if (good[x] && good[y]) {sum++;} else if (x == y) {deg[x]++;} else if (good[x]) {deg[y]++;} else if (good[y]) {deg[x]++;} else {edge[{ x, y }]++;}}int ans = 0;for (auto [e, w] : edge) {auto [x, y] = e;ans = max(ans, deg[x] + deg[y] + w);}sort(deg.begin(), deg.end(), greater<>());ans = max(ans, deg[0] + deg[1]);ans += sum;cout << ans << "\n";}return 0;
}

K Strips

题目大意:铺地毯,黑地砖的不能铺,红地砖的一定要铺,求可不可以用最少的地毯完成,能得话输出可以的位置。

做法:任意两个黑的地砖之间找红色的,从遇到红色没有被遮住就铺一张,最后可能会铺到黑色(禁区),这时候可以进行平移,平移完成后,如果第一张毯子没有触碰到左黑色,即合法,开始讨论下一个区间。任意一个区间不满足就返回 -1.

我们可以在首尾增加两块黑砖,这样就不用考虑边界问题了。

#include<bits/stdc++.h>
#define int long long 
using namespace std;
typedef vector<int> vi;
typedef pair<int,int> pii;
typedef vector<pii> vii;
void solve() {int n, m, k, w;cin >> n >> m >> k >> w;vii v(n + m + 2);for (int i = 0; i < n; i++) {int x;cin >> x;v[i] = make_pair(x, 1);}for (int i = n; i < n + m; i++) {int x;cin >> x;v[i] = make_pair(x,0);}v[n + m] = make_pair(w + 1, 0);sort(v.begin(), v.end());vector<int> ans;int l = 0, r = 0;for (int i = 0; i < (int)v.size(); i++) {if (v[i].second == 1) continue;l = r, r = i;vi red_idx;for (int j = l + 1; j < r; j++) {//两黑之间找红,铺毯子red_idx.push_back(v[j].first);int tep = v[j].first;while (j + 1 < r && v[j + 1].first < tep + k) j++;}if (red_idx.empty()) continue;red_idx.push_back(v[i].first);for (int j = (int)red_idx.size() - 2; j >= 0; j--) {if (red_idx[j] + k > red_idx[j + 1]) {red_idx[j] = red_idx[j + 1] - k;}}if (red_idx[0] <= v[l].first) {cout << "-1\n";return;}for (int j = 0; j < (int)   red_idx.size() - 1; j++) {ans.push_back(red_idx[j]);}}cout << ans.size() << "\n";for (int x : ans) cout << x << " ";cout << "\n";
}
signed main() {ios_base::sync_with_stdio(false),cin.tie(0),cout.tie(0);int T;cin >> T;while (T --) {solve();}return 0;
}

M Ordainer of Inexorable Judgment

计算几何。
答案就是切线角度的最大差值。(必须小于Π)
大于就要特殊处理,让2Π - 最大的空白区域。

这是计算几何的模板,可以实现向量加减法,相等判断,极角计算,线段长度计算等。

int sgn(T x) {return (fabs(x) <= eps) ? 0 : (x < 0 ? -1 : 1);
}struct P {T x, y;P() : x(0), y(0) {}P(T x, T y) : x(x), y(y) {}P(T r, double alpha, int _) : x(r * cos(alpha)), y(r * sin(alpha)) {}bool operator==(P o) { return sgn(x - o.x) == 0 && sgn(y - o.y) == 0; }P operator+(P o) { return P(x + o.x, y + o.y); }P operator-(P o) { return P(x - o.x, y - o.y); }T operator*(P o) { return x * o.y - y * o.x; }T operator^(P o) { return x * o.x + y * o.y; }friend double abs(P o) { return sqrt(o.x * o.x + o.y * o.y); }double angle() { double res = atan2(y, x); if (sgn(res) < 0) res += (2 * pi); return res; }
};

总代码:

#include <bits/stdc++.h>
using namespace std;
using ll = long long;using T = double;
const double eps = 1e-9, pi = acos(-1.0);
int sgn(T x) {return (fabs(x) <= eps) ? 0 : (x < 0 ? -1 : 1);
}struct P {T x, y;P() : x(0), y(0) {}P(T x, T y) : x(x), y(y) {}P(T r, double alpha, int _) : x(r * cos(alpha)), y(r * sin(alpha)) {}bool operator==(P o) { return sgn(x - o.x) == 0 && sgn(y - o.y) == 0; }P operator+(P o) { return P(x + o.x, y + o.y); }P operator-(P o) { return P(x - o.x, y - o.y); }T operator*(P o) { return x * o.y - y * o.x; }T operator^(P o) { return x * o.x + y * o.y; }friend double abs(P o) { return sqrt(o.x * o.x + o.y * o.y); }double angle() { double res = atan2(y, x); if (sgn(res) < 0) res += (2 * pi); return res; }
};int main() {int n;cin >> n;P P0;cin >> P0.x >> P0.y;double t0 = P0.angle();int rad, t;cin >> rad >> t;vector<double> alpha;  // 存所有的倾斜角for (int i = 0; i < n; i++) {P Q;cin >> Q.x >> Q.y;double phi = acos(rad / abs(Q));alpha.push_back((Q - P(rad, (Q.angle() + phi), 1)).angle());alpha.push_back((Q - P(rad, (Q.angle() - phi), 1)).angle());}for (int i = 0; i < 2 * n; i++) {alpha[i] -= t0;if (alpha[i] < 0) alpha[i] += 2 * pi;}double L = -1, R = -1;sort(alpha.begin(), alpha.end());bool flag = 1;if (alpha[0] + pi > alpha.back()) {//角度小于pi正着算L = alpha[0], R = alpha.back();flag = 0;} else for (int i = 1; i < 2 * n; i++) {//角度大于pi反着算if (alpha[i - 1] + pi < alpha[i]) {L = alpha[i - 1], R = alpha[i];}}double q = floor(t / (2 * pi));  double r = fmod(t, (2 * pi));    double ans = q * (R - L);  if (r > L) ans += r - L;if (r > R) ans -= r - R;  //加多了,减掉多余的 cout << fixed << setprecision(12);if (flag) {cout << (t - ans) << '\n';} else {cout << ans << '\n';}return 0;
}

B Birthday Gift

思维题,无论如何,奇数位上的0 ,1一定可以和偶数位上的0,1消除。

#include<bits/stdc++.h> 
#define int long long
const int N = 2e5 + 5;
using namespace std;
void solve(){string s;cin >> s;int a[2][2] = {0};int cnt2 = 0;for(int i = 0; i < (int)s.size(); i++){if(s[i] == '2'){cnt2 ++;}else{a[i&1][s[i] - '0'] ++; }}int cnt1 = abs(a[1][1] - a[0][1]);int cnt0 = abs(a[1][0] - a[0][0]);int tep = min(cnt1, cnt2);cnt1 -= tep;cnt2 -= tep;tep = min(cnt0, cnt2);cnt2 -= tep;cnt0 -= tep;if(cnt2 == 0){cout << cnt1 + cnt0 << '\n';}else{cout << cnt2 % 2 << '\n';}
}
signed main( ){ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);int T;cin >> T;while(T --){solve();}return 0;
}

二叉树

每次询问都要至少剪枝一半才可以保证在log2(n)次数内找到所需点。
于是,可以考虑树的重心,直到最后只剩下一个点极为答案。

#include<bits/stdc++.h>
#define int long long
using namespace std;
void solve() {int n;cin >> n;auto query = [&](int x, int y) {cout << "? " << ++x << " " << ++y << endl;cin >> x;return x;};auto answer = [&](int x) {cout << "! " << ++x << endl;};//建图vector<vector<int>> E(n);for (int i = 0; i < n; i++) {int x, y;cin >> x >> y;x--, y--;if (x != -1) E[i].push_back(x), E[x].push_back(i);if (y != -1) E[i].push_back(y), E[y].push_back(i);}int s = 0;while (1) {
//--------------------树的重心求法-----------------------//vector<int> siz(n), mss(n);auto dfs = [&](auto && self, int u, int fa) -> void{//这里void必须写,因为推断不出返回值siz[u] = 1;for (auto v: E[u]) {if (v != fa) {self(self, v, u);siz[u] += siz[v];mss[u] = max(mss[u], siz[v]);}}};dfs(dfs, s, -1);int ctr;//重心int tot = siz[s];for (int u = 0; u < n; u++) {mss[u] = max(mss[u], tot - siz[u]);//上面的子树节点数if (siz[u] && mss[u] <= tot / 2) ctr = u;}
//-------------------------------------------------------------//if (E[ctr].empty()) {answer(ctr);return;} else if (E[ctr].size() == 1) {int x = query(ctr, E[ctr][0]);if (x == 0) {answer(ctr);return;} else {answer(E[ctr][0]);return;}} else {sort(E[ctr].begin(), E[ctr].end(), [&](const int u, const int v) {return mss[u] < mss[v];});//排序重心节点的子树int x = query(E[ctr][0], E[ctr][1]);if (x == 0) {  // d(u) < d(v)s = E[ctr][0];E[s].erase(find(E[s].begin(), E[s].end(), ctr));//把从s到ctr(重心)的边删除,实现剪枝。} else if (x == 2) {s = E[ctr][1];E[s].erase(find(E[s].begin(), E[s].end(), ctr));} else {s = ctr;E[s].erase(E[s].begin(),E[s].begin() + 2);//删除前两条边剪枝,左闭右开}}}
}signed main() {ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);int T;cin >> T;while (T--) {solve();}return 0;
}
http://www.dtcms.com/a/462685.html

相关文章:

  • javascript开发平台
  • DTD 构建模块
  • 嵌入式MCU文件系统技术分享:从选型到FatFS深度应用
  • 手机淘宝客网站建设网页游戏平台软件
  • 企业网站备案怎么搞网站管理助手v3
  • fish怎么用英语说
  • 【NCCL】Ring Allreduce
  • 压缩感知的波达方向估计技术
  • 如何查网站关键词重庆免费网站制作
  • gps的时间基准
  • 网站策划案4500企业黄页的含义是什么
  • 李笑来做的一个网站火是用什么做的视频网站
  • Unity各种报错问题 定位与解决
  • Spring 面试宝典
  • 阳朔县建设规划局网站备案域名租用
  • 网站建设需要哪些工具与知识wordpress图片分享主题
  • 智能化 DDOS 防护平台架构与演进方向
  • 中石化网站是哪个公司做的做企业网站用什么框架
  • 第二步:创建写接口的模块,建立moogodb数据库连接,写添加与查询接口
  • 滑动窗口题目:K 个不同整数的子数组
  • qq网站临时会话静态网站跟动态的区别
  • 阿里云万网建网站家居企业网站建设报价
  • VBA效率大揭秘:选对数据结构,性能飙升300%!
  • LLM 论文精读(九)A Survey of Reinforcement Learning for Large Reasoning Models
  • The “Next“-价值度量与评估
  • 深圳营销网站建设多少钱frontpage网页制作实例
  • 家用电器行业外贸建站世界工厂采购网app
  • synchronized (Java)
  • LINUX——调试器gdb/cgdb的使用
  • GIS实战:投影变换教程与问题解答(上)