【牛客】2024暑期牛客多校6 补题记录

server/2024/9/25 17:16:56/

文章目录

  • A - Cake(树上dp)
  • B - Cake 2(暴力)
  • D - Puzzle: Wagiri(tarjan)
  • F - Challenge NPC 2(构造)
  • H - Genshin Impact's Fault(签到)
  • I - Intersecting Intervals(dp)

A - Cake(树上dp)

  • 首先两个人依次从一棵树的根走向叶子结点,对于每个结点,它的前缀结点都是确定的,所以先计算出走到每个结点时的 0 0 0 在所有前缀字符串中的占比 p p p(取最大,因为最后切蛋糕的人想让 0 0 0 最多)
  • 第一个人想尽可能让 1 1 1 更多,也就是让 p p p 更小,第二个人想让 p p p 更大,那第一个人操作的时候尽可能让 p p p 小,第二个人尽可能让 p p p 更大就可以了
#include <bits/stdc++.h>using namespace std;#define int long long
#define double long double
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 maxn = 1e6;
const int MAXN = 1e5 + 10;
const int mod = 1e9 + 7;
const int mod1 = 954169327;
const int mod2 = 906097321;
const int INF = 0x3f3f3f3f3f3f3f3f;void solve()
{int n; cin >> n;vector<vector<PII>> g(n + 1);for (int i = 1; i < n; i ++ ){int u, v, c;cin >> u >> v >> c;g[u].push_back({v, c});g[v].push_back({u, c});}vector<int> dep(n + 1);vector<double> f(n + 1);vector<vector<int>> cnt(n + 1, vector<int>(2));function<void(int, int)> dfs = [&](int u, int fa){if (u != 1) f[u] = max(f[u], (double)(1.0 * cnt[u][0] / (cnt[u][0] + cnt[u][1])));for (int i = 0; i < g[u].size(); i ++ ){int j = g[u][i].first, c = g[u][i].second;if (j == fa) continue;dep[j] = dep[u] + 1;cnt[j][0] = cnt[u][0], cnt[j][1] = cnt[u][1];cnt[j][c] ++ ;f[j] = f[u];dfs(j, u);}};dep[1] = 1;dfs(1, -1);vector<double> ans(n + 1);function<void(int, int)> dp = [&](int u, int fa){int sz = 0;if (dep[u] & 1) ans[u] = 1;for (int i = 0; i < g[u].size(); i ++ ){int j = g[u][i].first, c = g[u][i].second;if (j == fa) continue;dp(j, u);sz ++ ;if (dep[u] & 1) ans[u] = min(ans[u], ans[j]);else ans[u] = max(ans[u], ans[j]);}if (sz == 0) ans[u] = f[u];};dp(1, -1);printf("%.12Lf\n", 1 - ans[1]);
}signed main()
{// ios::sync_with_stdio(false);// cin.tie(0), cout.tie(0);int t = 1;cin >> t;while (t--){solve();}return 0;
}

B - Cake 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 = 1e6 + 10;
const int maxn = 1e6 + 10;
const int mod = 1e9 + 7;
const int mod1 = 954169327;
const int mod2 = 906097321;
const int INF = 0x3f3f3f3f3f3f3f3f;void solve()
{int n, k;cin >> n >> k;if (n == k * 2){cout << n << '\n';return;}k = min(k, n - k);queue<int> q;q.push(k % n);int cnt = 1;int ans = 2;for (int i = 1; i < n; i ++ ){int tmp = (i + k) % n;q.push(tmp);int top = -1;if (q.size()) top = q.front();if (top == i){q.pop();cnt -- ;}if (tmp < i) ans += (cnt + tmp) + 1;else ans += cnt + 1;cnt ++ ;}cout << ans << '\n';
}signed main()
{ios::sync_with_stdio(false);cin.tie(0), cout.tie(0);int t = 1;// cin >> t;while (t--){solve();}
}

D - Puzzle: Wagiri(tarjan)

  • 首先只看轮边,跑边的双连通分量找桥,所有的桥都不在环上,所以轮边不包括桥,然后将所有不是桥的轮边加到答案里并更新并查集
  • 遍历所有切边,在同一个并查集的两个点之间必不连切边
#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 = 1e6 + 10;
const int maxn = 1e6 + 10;
const int mod = 1e9 + 7;
const int mod1 = 954169327;
const int mod2 = 906097321;
const int INF = 0x3f3f3f3f3f3f3f3f;void solve()
{int n, m;cin >> n >> m;vector<vector<int>> g(n + 1);vector<PII> qb, lb, ans;for (int i = 0; i < m; i ++ ){int u, v; cin >> u >> v;string s; cin >> s;if (s[0] == 'L'){g[u].push_back(v);g[v].push_back(u);lb.push_back({u, v});}else qb.push_back({u, v});}int timestamp = 0;vector<int> fa(n + 1), dfn(n + 1), low(n + 1);set<PII> bridge;function<void(int, int)> tarjan = [&](int u, int father){fa[u] = father;dfn[u] = low[u] = ++ timestamp;for (int i = 0; i < g[u].size(); i ++ ){int j = g[u][i];if (!dfn[j]){tarjan(j, u);low[u] = min(low[u], low[j]);if (dfn[u] < low[j]){bridge.insert({j, fa[j]});bridge.insert({fa[j], j});}}else if (dfn[j] < dfn[u] && j != father)low[u] = min(low[u], dfn[j]);}};for (int i = 1; i <= n; i ++ )if (!dfn[i]) tarjan(i, -1);vector<int> p(n + 1);for (int i = 1; i <= n; i ++ ) p[i] = i;function<int(int)> find = [&](int u){if (u != p[u]) p[u] = find(p[u]);return p[u];};for (auto t : lb){int u = t.first, v = t.second;if (bridge.count(t)) continue;int pu = find(u), pv = find(v);if (pu != pv) p[pu] = pv;ans.push_back(t);}for (int i = 1; i <= n; i ++ ) find(i);for (auto t : qb){int u = t.first, v = t.second;int pu = find(u), pv = find(v);if (pu != pv){ans.push_back({u, v});p[pu] = pv;}}int p1 = find(1);for (int i = 2; i <= n; i ++ ){if (find(i) != p1){cout << "NO\n";return;}}cout << "YES\n";cout << (int)(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();}
}

F - Challenge NPC 2(构造)

队友的代码

#include<cstdio>
#include<vector>
struct node{int n;node *nxt;
}*mp[1000005],use[2000005],*nw;
void add(int u,int v)
{node *p=nw++;p->n=v;p->nxt=mp[u];mp[u]=p;
}
int du[1000005];
int base;
std::vector<int> dp[1000005];
int dfs(int now,int fa=-1,int dep=1)
{du[now]=1000000000;dp[dep+base].push_back(now);int ret=dep;node *p=mp[now];while(p){if(p->n!=fa){int r=dfs(p->n,now,dep+1);if(r>ret) ret=r;}p=p->nxt;}return ret;
}
int ans[1000005],ansl;
bool fl[1000005];
int main()
{int T;scanf("%d",&T);while(T--){int n,m;scanf("%d%d",&n,&m);for(int i=1;i<=n;i++)mp[i]=0,du[i]=0,fl[i]=0;fl[1]=fl[2]=fl[3]=0;nw=use;ansl=0;base=0;for(int i=1;i<=m;i++){int u,v;scanf("%d%d",&u,&v);add(u,v);add(v,u);du[u]++;du[v]++;}for(int i=1;i<=n;i++)if(du[i]<=1){if(du[i]==0){base++;dp[base].push_back(i);fl[base]=1;}else base+=dfs(i);}if(base<=3){if(fl[1]||fl[2]||fl[3]){if(fl[1]){for(int i=0;i<dp[2].size();i++)ans[ansl++]=dp[2][i];for(int i=0;i<dp[1].size();i++)ans[ansl++]=dp[1][i];for(int i=0;i<dp[3].size();i++)ans[ansl++]=dp[3][i];					}else{for(int i=0;i<dp[2].size();i++)ans[ansl++]=dp[2][i];for(int i=0;i<dp[1].size();i++)ans[ansl++]=dp[3][i];for(int i=0;i<dp[3].size();i++)ans[ansl++]=dp[1][i];	}for(int i=0;i<ansl;i++)printf("%d ",ans[i]);goto label;				}printf("-1");goto label;}for(int i=2;i<=base;i+=2)for(int j=0;j<dp[i].size();j++)ans[ansl++]=dp[i][j];for(int i=1;i<=base;i+=2)for(int j=0;j<dp[i].size();j++)ans[ansl++]=dp[i][j];for(int i=0;i<ansl;i++)printf("%d ",ans[i]);label:putchar('\n');for(int i=1;i<=base;i++)dp[i].clear();}return 0;
}

H - Genshin Impact’s Fault(签到)

#include<cstdio>
#include<cstring>
char s[1000005];
int main()
{int T;scanf("%d",&T);while(T--){scanf("%s",s);int len=strlen(s);int lst=1;for(int i=0;i<=len-10;i++){int cnt=0;for(int j=i;j<i+10;j++)if(s[j]=='3') cnt++;if(cnt==10){printf("invalid\n");goto label;}}for(int i=0;i<=len-90;i++){int cnt=0;for(int j=i;j<i+90;j++)if(s[j]=='3'||s[j]=='4') cnt++;if(cnt==90){printf("invalid\n");goto label;}}for(int i=0;i<len;i++){if(s[i]=='U') lst=1;if(s[i]=='5'){if(lst==0){printf("invalid\n");goto label;}lst=0;}}printf("valid\n");label:;}return 0;
}

I - Intersecting Intervals(dp)

  • f [ i ] [ j ] f[i][j] f[i][j] 表示第 i i i 行,第 j j j 个必选的最优答案
  • 上下两行相交只会是这两种情况:
    在这里插入图片描述
  • k < j k<j k<j 时,首先肯定加上 f [ i − 1 ] [ k ] f[i-1][k] f[i1][k],然后因为 [ k , j ] [k,\ j] [k, j] 必选,所以还要加上 s u m k , j sum_{k,\ j} sumk, j k k k 的左边随便选多少,记作 p r e [ k ] pre[k] pre[k] j j j 的右边随便选多少,记作 s u f [ j ] suf[j] suf[j]
  • k > j k>j k>j 时,首先肯定加上 f [ i − 1 ] [ k ] f[i-1][k] f[i1][k],然后因为 [ j , k ] [j,\ k] [j, k] 必选,所以还要加上 s u m j , k sum_{j,\ k} sumj, k j j j 的左边随便选多少,记作 p r e [ j ] pre[j] pre[j] k k k 的右边随便选多少,记作 s u f [ k ] suf[k] suf[k]
  • 直接枚举 k k k 的话会超时,我们可以利用前缀和后缀记录最优的 k k k
#include <bits/stdc++.h>using namespace std;#define int long long
#define double long double
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 maxn = 1e6;
const int MAXN = 1e5 + 10;
const int mod = 1e9 + 7;
const int mod1 = 954169327;
const int mod2 = 906097321;
const int INF = 0x3f3f3f3f3f3f3f3f;void solve()
{int n, m;cin >> n >> m;vector<vector<int>> a(n + 1, vector<int>(m + 1));vector<int> f(m + 2), l0(m + 2), l1(m + 2), r0(m + 2), r1(m + 2);for (int i = 1; i <= n; i ++ ){for (int j = 1; j <= m; j ++ ){cin >> a[i][j];l0[j] = max(0ll, l0[j - 1]) + a[i][j];if (j == 1) l1[j] = f[j] + l0[j];else l1[j] = max(l0[j] + f[j], l1[j - 1] + a[i][j]);}for (int j = m; j >= 1; j -- ){r0[j] = max(0ll, r0[j + 1]) + a[i][j];if (j == m) r1[j] = f[j] + r0[j];else r1[j] = max(r0[j] + f[j], r1[j + 1] + a[i][j]);}for (int j = m; j >= 1; j -- ){f[j] = max(l0[j] - a[i][j] + r1[j], r0[j] - a[i][j] + l1[j]);}}int ans = -INF;for (int i = 1; i <= m; i ++ ) ans = max(ans, f[i]);cout << ans << '\n';
}signed main()
{ios::sync_with_stdio(false);cin.tie(0), cout.tie(0);int t = 1;cin >> t;while (t--){solve();}return 0;
}

http://www.ppmy.cn/server/98549.html

相关文章

MySQL——设置表的字段值自动增加

在数据表中&#xff0c;若想为表中插人的新记录自动生成唯一的 ID&#xff0c;可以使用 AUTOINCREMENT约束来实现。AUTOINCREMENT 约束的字段可以是任何整数类型默认情况下&#xff0c;该字段的值是从1开始自增的。使用 AUTO_INCREMENT 设置表字段值自动增加的基本语法格式如下…

vue2跨域下载图片

背景 众所周知&#xff0c;当网站跨域后会有很多限制的&#xff0c;今天讲述跨域图片无法下载的问题。 实现思路 正常直接保存时不行的&#xff0c;比如a标签之类的都行不通&#xff1a; // 这是不行的&#xff0c;对于跨域来讲const el document.createElement("a&q…

LabVIEW位移检测系统

工业控制器的位移检测在保证机械设备精确运行中发挥着重要的作用。开发了一种基于LabVIEW的高精度位移检测系统&#xff0c;该系统通过集成硬件与软件的优化配置&#xff0c;实现了对工业控制器位移的精确测量和分析。 项目背景 在传统工业生产中&#xff0c;位移检测系统往往…

计算机网络中接收窗口与门限值的区别

计算机网络中接收缓存和门限值的关系主要体现在TCP的流量控制和拥塞控制机制中。‌ TCP&#xff08;‌传输控制协议&#xff09;‌是一种面向连接的、‌可靠的、‌基于字节流的传输层通信协议。‌在TCP中&#xff0c;‌接收缓存的大小由接收端根据其可用资源&#xff08;‌如内…

SSRS rdlc报表 九 在.net core中使用RDLC报表

开发环境 vs 2022企业版 SqlServer数据库 Win11 前言 rdlc报表在aspx中集成的很好,很容易实现,并且功能强大,但随着技术的发展,aspx慢慢的被淘汰,现在已经发展到.net8了,aspx基本上很少用,出的新框架基本上也都是前后端分离,没了aspx的控件加持,rdlc这么厉害的报…

gin框架传入的gin.context参数是池化的

1. gin.context参数不但是池化的&#xff0c;而且是指针 2. 但是gin.context又实现了context的接口。因此&#xff0c;可以当作context去使用 3. 这就会导致一个很严重的问题&#xff1a; 1. 池化导致了复用后的ctx将会将之前使用的ctx中的内容进行覆盖。 2. 实现了context接…

代码随想录第六十六天打卡

今天大家会感受到 Bellman_ford 算法系列在不同场景下的应用。 建议依然是&#xff1a;一刷的时候&#xff0c;能理解 原理&#xff0c;知道Bellman_ford 解决不同场景的问题 &#xff0c;照着代码随想录能抄下来代码就好&#xff0c;就算达标。 二刷的时候自己尝试独立去写&am…

三大机器学习框架对比:TensorFlow、PyTorch与Scikit-Learn

目录 前言 概述 TensorFlow PyTorch Scikit-Learn 总结 前言 本篇旨在深入探讨三种主流机器学习框架——TensorFlow、PyTorch与Scikit-Learn。随着数据科学和人工智能领域的快速发展&#xff0c;这些框架已成为构建和部署机器学习模型的关键工具。鉴于每种框架的特点和优…