【2021ICPC沈阳】EFBJHL

news2024/12/28 2:08:07

 不知道为什么感觉以前的场要比现在的简单一点,虽然这场VP虽然题数到了但是还是差点罚时....

现在的有些场感觉连签到都要签半天,比如前几天的ICPC西安和CCPC桂林,看了下题都不简单

这场甚至银牌题都没什么思维,只需要算法的板子和一点点思维就能做出来

Problems - Codeforces

E. Edward Gaming, the Champion

题意

问字符串里面有多少edgnb

思路

直接模拟即可

#include <bits/stdc++.h>

constexpr int N = 1e5 + 10;

void solve(){
	std::string s;
	std::cin >> s;
	int n = s.size();
	s = " " + s;
	int ans = 0;
	for (int i = 1; i + 4 <= n; i ++) {
		if (s[i] == 'e' && s[i + 1] == 'd' && s[i + 2] == 'g' && s[i + 3] == 'n' && s[i + 4] == 'b') {
			ans ++;
		}
	}
	std::cout << ans << "\n";
}
signed main(){
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);

    int t = 1;
    while(t --) {
        solve();
    }
    return 0;
}

F. Encoded Strings I

题意

思路

n的范围是1000, 因此做法就是直接枚举前缀然后统计最大的编码字符串,直接扔进set即可

#include <bits/stdc++.h>

constexpr int N = 1e5 + 10;

std::string s;

int n;
int p[N];

void solve(){
	std::cin >> n >> s;
	s = " " + s;

	std::set<std::string> S4;
	for (int i = 1; i <= n; i ++) {
		std::string t = s.substr(1, i);
		int m = t.size();
		t = " " + t;
		std::map<char, int> last;
		for (int i = 1; i <= m; i ++) {
			last[t[i]] = i;
		}
		std::set<char> S;
		for (int i = m; i >= 1; i --) {
			S.insert(t[i]);
			p[i] = S.size();
		}
		std::string res;
		for (int i = 1; i <= m; i ++) {
			res = res + (char)('a' + p[last[t[i]] + 1]);
		}
		S4.insert(res);
	}
	std::cout << (*S4.rbegin()) << "\n";
}
signed main(){
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);

    int t = 1;
    while(t --) {
        solve();
    }
    return 0;
}

B. Bitwise Exclusive-OR Sequence 

题意

思路

位运算的题直接当成01矩阵去看就行

一开始想的做法是直接贪心,对于一个数的第 j 位,如果和这个数的异或为1的个数大于异或为0的个数,那么就把这个数的第 j 位置为 1,这样异或之后0就比1多了

但是这样的正确性不能保证,这样只能保证对于这个数相连的所有数组成的这个集合而言是对的,放在树上其实就是只考虑了结点 u 放出去的边的所有 v构成的这样的集合,没有考虑整棵树

这样的模型显然是要往树上问题考虑的

这些约束条件连边之后,形成了若干棵树,也就是森林,当根结点的值唯一确定了,其他所有结点的值也就确定了

这里做法考虑按位贪心,对于第 j 位,如果置0之后这棵树第 j 位的1比0多,那么这位一定置0,这样就把根的值确定了 

那么算出这棵树的所有的结点的值的和什么做法合适呢,考虑变化量, 根节点在全是0和根的值a1 之间的变化量就是所有结点 ^ a1,加上这个变化量即可

还有就是判无解,并不是存在环就是无解,如果存在环且异或值围着环算起来没问题也是有解的

#include <bits/stdc++.h>

#define int long long

constexpr int N = 2e5 + 10;

std::vector<int> V[N];
std::vector<std::pair<int, int> > adj[N];

int n, m;
int pre[N], pre2[N];
int st[N];

void dfs(int u, int s) {
	for (auto [v, w] : adj[u]) {
		if (st[v]) {
			if ((pre[u] ^ w) != pre[v]) {
				std::cout << -1 << "\n";
				exit(0);
			}
		}else {
			st[v] = 1;
			pre[v] = pre[u] ^ w;
			V[s].push_back(v);
			dfs(v, s);
		}
	}
}
void solve(){
	std::cin >> n >> m;
	bool ok = true;
	for (int i = 1; i <= m; i ++) {
		int u, v, w;
		std::cin >> u >> v >> w;
		adj[u].push_back({v, w});
		adj[v].push_back({u, w});
	}

	int ans = 0;
	for (int i = 1; i <= n; i ++) {
		if (!st[i]) {
			st[i] = 1;
			dfs(i, i);
			int a1 = 0;
			for (int j = 30; j >= 0; j --) {
				int s = 0;
				for (auto x : V[i]) {
					if ((pre[x] >> j) & 1) {
						s ++;
					}
				}
				if (s > V[i].size() - s) a1 += (1 << j);
			}
			int res = a1;
			for (auto x : V[i]) {
				res += (pre[x] ^ a1);
			}
			ans += res;
		}
	}
	std::cout << ans << "\n";
}
signed main(){
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);

    int t = 1;
    while(t --) {
        solve();
    }
    return 0;
}

J. Luggage Lock

题意

思路

直接BFS即可,注意多测,因此需要BFS预处理dis数组,直接算即可

#include <bits/stdc++.h>

#define int long long

constexpr int N = 2e5 + 10;

std::string a, b;
std::queue<std::string> q;
std::map<std::string, int> vis, dis;

int n;

char calc(char x, int ty) {
	if (ty == 0) {
		if (x == '0') x = '9';
		else x = (char)(x - 1);
	}else {
		if (x == '9') x = '0';
		else x = (char)(x + 1);
	}
	return x;
}
void bfs(std::string u) {
	std::string t = u;
	t = " " + t;
	q.push(t);
	vis[t] = 1;
	while(!q.empty()) {
		std::string x = q.front();
		q.pop();
		for (int l = 1; l <= 4; l ++) {
			for (int r = l; r <= 4; r ++) {
				std::string v = x;
				for (int j = l; j <= r; j ++) {
					v[j] = calc(v[j], 0);
				}
				if (!dis.count(v)) {
					dis[v] = dis[x] + 1;
					q.push(v);
				}

				v = x;
				for (int j = l; j <= r; j ++) {
					v[j] = calc(v[j], 1);
				}
				if (!dis.count(v)) {
					dis[v] = dis[x] + 1;
					q.push(v);
				}
			}
		}
	}
}
void solve(){
	std::cin >> a >> b;
    a = " " + a;
    b = " " + b;
	std::string c = " 0000";
	for (int i = 1; i <= 4; i ++) {
		c[i] = (b[i] - '0' - (a[i] - '0') + 10) % 10;
		c[i] = c[i] + '0';
	}
	std::cout << dis[c] << "\n";
}
signed main(){
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);

    int t = 1;
	bfs("0000");
	std::cin >> t;
    while(t --) {
        solve();
    }
    return 0;
}

 

H. Line Graph Matching

题意

思路

首先根据定义,问题转化成 用相邻边 把整个图占满的权重之和

显然如果边数为偶数,直接就是边权之和,那么边数是奇数呢

奇数的情况我们需要考虑不占一条边,把其他的占满,很自然地想到了枚举这条边

但事实上这条边需要满足一些条件,如果这边断开之后变成两个连通块了,这两个连通块的边数都必须是偶数,而不能是奇数+奇数。如果不是割边,那就没问题,直接不选这条边即可

那不就是割边吗,我们只需要在跑割边的过程中把连通块的边数统计一下,标记一下哪些边是合法的, 统计哪条边是合法边中边权最小的即可,然后减掉这个边就是答案了

#include <bits/stdc++.h>

#define int long long

constexpr int N = 2e5 + 10;

std::vector<std::pair<int, int> > adj[N];

int n, m;
int idx = 0;
int mi = 1e9;
int cnt[N];
int dfn[N], low[N];

void tarjan(int u, int fa) {
    dfn[u] = low[u] = ++ idx;
    for (auto [v, w] : adj[u]) {
        if (!dfn[v]) {
            tarjan(v, u);
            cnt[u] += cnt[v] + 1;
            low[u] = std::min(low[u], low[v]);
            if (low[v] > dfn[u]) {
                if (cnt[v] % 2 == 0) {
                    mi = std::min(mi, w);
                }
            }else {
                mi = std::min(mi, w);
            }
        }else if (dfn[v] < dfn[u] && v != fa) {
            cnt[u] ++;
            mi = std::min(mi, w);
            low[u] = std::min(low[u], dfn[v]);
        }
    }
}
void solve(){
    std::cin >> n >> m;
    int ans = 0;
    for (int i = 1; i <= m; i ++) {
        int u, v, w;
        std::cin >> u >> v >> w;
        adj[u].push_back({v, w});
        adj[v].push_back({u, w});
        ans += w;
    }
    tarjan(1, 0);
    if (m & 1) ans -= mi;
    std::cout << ans << "\n";
}
signed main(){
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);

    int t = 1;
    while(t --) {
        solve();
    }
    return 0;
}

L. Perfect Matchings

题意

思路

首先 删边 其实可以看作是给这些边 染色,这样能直观一点

那么其实就是染了一棵树,然后让我们在求没被染的边中选 n 条边使得这些边之间没有公共顶点 的 方案数

正着难求,我们考虑容斥,即总方案数 - 不合法方案的并集

容斥的话,考虑在树上选了 k 条边的方案数,这样是 (-1)^k * val

这个val考虑树上背包

设 dp[u][v][0/1] 为 u这棵子树中,选了 v 条边,u结点是否是边的一部分的方案数,转移就是 dls 那个树上背包的转移

不过要分和根结点连的那条边是否被选,如果被选的话 u 和 v 都不能被选,然后和根连着的那条边单独计算,详细看代码

然后要在非树的部分选边,这个算组合数即可

#include <bits/stdc++.h>

#define int long long

constexpr int N = 4e3 + 10;
constexpr int mod = 998244353;

std::vector<int> adj[N];

int n;
int sz[N];
int dp[N][N][2];
int p[N];

void dfs(int u, int fa) {
    sz[u] = dp[u][0][0] = 1;
    for (auto v : adj[u]) {
        if (v == fa) continue;
        dfs(v, u);
        for (int k = sz[u] / 2; k >= 0; k --) {
            for (int l = sz[v] / 2; l >= 0; l --) {
                if (l > 0) {
                    dp[u][k + l][0] += dp[u][k][0] * (dp[v][l][0] + dp[v][l][1]) % mod, dp[u][k + l][0] %= mod;
                    dp[u][k + l][1] += dp[u][k][1] * (dp[v][l][0] + dp[v][l][1]) % mod, dp[u][k + l][1] %= mod;
                }
                dp[u][k + l + 1][1] += dp[u][k][0] * dp[v][l][0] % mod, dp[u][k + l + 1][1] %= mod;
            }
        }
        /*for (int i = 0; i <= sz[u] + sz[v]; i ++) {
            dp[u][i][0] = tmp[i][0];
            dp[u][i][1] = tmp[i][1];
        }*/
        sz[u] += sz[v];
    }
}
void solve(){
    std::cin >> n;
    for (int i = 1; i <= 2 * n - 1; i ++) {
        int u, v;
        std::cin >> u >> v;
        adj[u].push_back(v);
        adj[v].push_back(u);
    }
    p[0] = 1;
    for (int i = 1; i <= n; i ++) {
        p[i] = p[i - 1] * (2 * i - 1) % mod;
    }
    dfs(1, 0);
    
    int ans = 0;
    for (int i = 0; i <= n; i ++) {
        if (i & 1) ans -= (dp[1][i][0] + dp[1][i][1]) * p[n - i] % mod;
        else ans += (dp[1][i][0] + dp[1][i][1]) * p[n - i] % mod;
        ans = (ans % mod + mod) % mod;
    }
    std::cout << ans << "\n";
}
signed main(){
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);

    int t = 1;
    while(t --) {
        solve();
    }
    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1150654.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

mmcv中出现TypeError: FormatCode() got an unexpected keyword argument ‘verify‘

最近安装Co-DETR项目环境时遇到如下的问题 主要是因为最新版的yapf&#xff08;0.40.2&#xff09;中删除了verify的验证功能 将其降级为旧版即可&#xff1a; pip install yapf0.40.0

照片去文字水印怎么弄?这三个方法快学起来

照片去文字水印怎么弄&#xff1f;你有没有遇到过这样的烦恼呢&#xff1f;我经常在网上找一些好看的照片来做头像或者壁纸&#xff0c;但是总是遇到一些带水印或者不想要的文字的照片&#xff0c;影响了整体的美观度让人很头疼&#xff0c;每次重新找又得花费不少时间和精力&a…

真心话坦白局系统源码

它具有匿名信息的神秘感 但又会给你一点小提示 能让你有无限挖掘下去的好奇感 也能让你说出那些不敢说出口的话 敢来一场坦白局吗&#xff01; 坦白局这个功能类似于悄悄话&#xff0c;只不过是匿名的悄悄话。 有时候我们有些话是开不了口的&#xff0c;坦白局给了我们一个…

每日汇评:黄金多头重回2000美元,接下来会发生什么?

受地缘政治因素影响&#xff0c;金价守住了上周五2000美元上方的强劲涨幅&#xff1b; 美元持稳&#xff0c;因为美国债券市场的行动是美联储本周的关键&#xff1b; 由于可能出现牛十字&#xff0c;黄金价格有望进一步上涨&#xff0c;牛旗仍在图表中延续&#xff1b; 继上周五…

vue3 vue3-particles粒子使用方法

注意&#xff1a;这个vue3-particles和particles.vue3有些许差别的&#xff08;安装、引入方式&#xff09; particles.vue3示例&#xff1a;vue3 使用particles插件粒子_vueparticles_余温无痕的博客-CSDN博客 下面是vue3-particles使用介绍 先看效果&#xff0c;背景图是自…

Qt3D绘制旋转立方体

近期用了款叫DesktopSpace&#xff0c;也想实现一下这款软件实现的效果 具体实现步骤: 使用Qt3D绘制个旋转的立方体&#xff08;一&#xff09;使用快捷键控制立方体显示面&#xff08;二&#xff09;创建6个人虚拟桌面&#xff0c;截取不同虚拟桌面&#xff0c;显示在不同的面…

15、SpringCloud -- 延迟消息、异步下单失败处理方案

目录 延迟消息需求理解:思路:代码:发送延迟消息消费延迟消息:1、订单支付状态:2、回补真实库存:3、回补预库存:4、修改本地标识:测试:清除MQ数据:期望结果:实际结果:问题:异步下单失败需求1:代码:发送消息:消费消息:测试:需求2:延迟消息 需求理解: 用户成…

从制造到创造:揭示中国制造的基础瓶颈及其突破

中国制造的产品遍布全球&#xff0c;但很多人认为中国制造的产品缺乏基础&#xff0c;这是为什么呢&#xff1f;本文将从制造的基础入手&#xff0c;探讨中国制造缺乏基础的原因。 一、制造的基础 制造的基础是工艺&#xff0c;工艺的基础包括三个方面&#xff1a;基础材料的研…

如何将word格式的文档转换成markdown格式的文档

如何将word格式的文档转换成markdown格式的文档 前言 A. 介绍Markdown和Word格式文档 什么是Markdown&#xff1f; Markdown是一种轻量级标记语言&#xff0c;旨在简化文本格式化和排版的过程。它以纯文本形式编写&#xff0c;通过使用简单的标记语法&#xff0c;使文档更具…

HarmonyOS开发:基于http开源一个网络请求库

前言 网络封装的目的&#xff0c;在于简洁&#xff0c;使用起来更加的方便&#xff0c;也易于我们进行相关动作的设置&#xff0c;如果&#xff0c;我们不封装&#xff0c;那么每次请求&#xff0c;就会重复大量的代码逻辑&#xff0c;如下代码&#xff0c;是官方给出的案例&am…

0003net程序设计-net旅游景点推荐系统

文章目录 摘 要目录系统设计开发环境 摘 要 随着信息技术和网络技术的飞速发展&#xff0c;人类已进入全新信息化时代&#xff0c;传统管理技术已无法高效&#xff0c;便捷地管理信息。为了迎合时代需求&#xff0c;优化管理效率&#xff0c;各种各样的管理系统应运而生&#…

【IDEA】设置sql提示

第一步&#xff1a;注入SQL语言 1.首先选择任意一条sql语句&#xff0c;右击&#xff0c;选择 ‘显示上下文操作’ 2.选择 ‘注入语言或引用’ 3. 往下翻&#xff0c;找到MySQL 第二步&#xff1a;配置MySQL数据库连接 1.首先点击侧边的数据库&#xff0c;再点击上面的加号 2…

antv/g6使用教程及图配置

介绍 G6 是一款由蚂蚁金服 AntV 团队开发的 JavaScript 图形引擎&#xff0c;用于构建各种交互式可视化图形&#xff0c;包括但不限于图表、网络拓扑图、关系图、流程图等。无论是数据分析、决策支持&#xff0c;还是信息可视化&#xff0c;G6 都是一个强大的工具。 以下是 G…

python采集电商jd app商品详情数据(2023-10-30)

一、技术要点&#xff1a; 1、cookie可以从手机app端用charles抓包获取&#xff1b; 2、无需安装nodejs&#xff0c;纯python源码&#xff1b; 3、商品详情接口为&#xff1a;functionId "wareBusiness"&#xff1b; 4、clientVersion "10.1.4"同…

自学C语言的最恐怖的地方是什么?

自学C语言的最恐怖的地方是什么&#xff1f; 当年在网吧学C&#xff0c;人家在玩游戏&#xff0c;我在敲代码&#xff0c;基本上从9点敲到1点&#xff0c;然后再开始玩游戏。。。当时不是装逼&#xff0c;就是觉得有意思&#xff0c;而且当时计算机的确是一门很高大上的职业。…

redis加入window服务及删除

1、命令redis-server.exe --service-install redis.windows.conf&#xff0c;在服务中可配置自动启动 删除redis服务&#xff0c;先停止redis服务运行&#xff0c;管理员cmd模式&#xff0c;sc delete "redis" ,

mysql 间隙锁

mysql 默认是可重复读的隔离级别&#xff0c;这种默认会有幻读&#xff0c;幻读指的什么现象呢&#xff0c;就是在同一个事物中前后两次查到的结果不一致&#xff0c;那么mysql是怎么解决幻读的呢&#xff0c;这就是mvcc mvcc 什么是mvcc呢&#xff0c;就是多版本并发控制&am…

数据结构之树(图解)

文章目录 前言一、树是什么&#xff1f;二、树的特点三、树的相关概念四、树的表示方法&#xff08;孩子兄弟表示法&#xff09;总结 前言 在学习完线性结构&#xff0c;例如顺序表、链表、栈、队列后&#xff0c;我们要开始学习一个新的数据结构----树 一、树是什么&#xf…

超全整理,Jmeter性能测试-脚本error报错排查/分布式压测(详全)

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 性能脚本error报错…

iOS 使用dsym符号化线上crash日志(ips文件)

1.获取崩溃日志 可以iphone连接mac复制当时的崩溃日志。 Xcode->Window->Devices View Device Logs 如果是testflight的崩溃是可以分享的&#xff0c;分享出来可能是ips文件。 把文件名称改成my.crash 使用脚本把新版本崩溃日志转成老版本格式 这一步不是必须的&…