CodePlus 第五次网络赛 掐指会算

2024-02-03 05:38

本文主要是介绍CodePlus 第五次网络赛 掐指会算,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

失踪人口暂时回归。
临近 NOIP 了,退役选手准备打一打 Div.2 来练练手(应该不是天气冷了,没衣服穿了
游戏体验差,OJ 又和第一次一样卡了半天。


T1 我有矩阵,你有吗?

根据异或的性质,不难发现 A A A 矩阵的每行每列最多只能异或一次。
所以我们可以假设 A A A 矩阵的第一行是否被异或了,然后把所有状态递推出来,最后判断一下是否符合题设。

#include <bits/stdc++.h>
using namespace std;
int F()
{int x = 0; char ch; bool minus = 0;while(ch = getchar(), (ch > '9' || ch < '0') && ch != '-');ch == '-' ? minus = 1 : x = ch - '0';while(ch = getchar(), ch <= '9' && ch >= '0') x = x * 10 + ch - '0';return minus ? -x : x;
}int n, m, x[1010], y[1010], A[1010][1010], B[1010][1010];
int main()
{scanf("%d %d", &n, &m);for(int i = 1; i <= n; ++i)for(int j = 1; j <= m; ++j)scanf("%d", &A[i][j]);for(int i = 1; i <= n; ++i)for(int j = 1; j <= m; ++j)scanf("%d", &B[i][j]);for(int i = 1; i <= m; ++i) if(A[1][i] != B[1][i]) y[i] = 1;for(int i = 1; i <= n; ++i)for(int j = 1; j <= m; ++j)if((A[i][j] ^ y[j] ^ x[i]) != B[i][j]) x[i] ^= 1;bool flag = 0;for(int i = 1; i <= n; ++i)for(int j = 1; j <= m; ++j)if((A[i][j] ^ x[i] ^ y[j]) != B[i][j])flag = 1;if(!flag){ puts("Koyi"); return 0; }memset(x, 0, sizeof(x)); memset(y, 0, sizeof(y));x[1] = 1;for(int i = 1; i <= m; ++i) if(A[1][i] == B[1][i]) y[i] = 1;for(int i = 1; i <= n; ++i)for(int j = 1; j <= m; ++j)if((A[i][j] ^ y[j] ^ x[i]) != B[i][j]) x[i] ^= 1;flag = 1;for(int i = 1; i <= n; ++i)for(int j = 1; j <= m; ++j)if((A[i][j] ^ x[i] ^ y[j]) != B[i][j])flag = 1;if(!flag){ puts("Koyi"); return 0; }puts("Budexing");return 0;
}

T2 逻辑树

一开始没看到在询问的都是叶结点,想了半天。

我想到的是一种构造方式,这种构造方式可以保证所有询问序列都是必要的,且根结点的取值一定为 1 1 1

假设只有三个点(一个根和两个叶子, a a a 点为先询问的叶子, b b b 为后询问的),假设根的运算符为 and ,那么 a a a 显然要取值为 1 1 1,才能保证询问 b b b 时不会跳过,若为 or,则 a a a 要为 0 0 0,按照这样的取值,根结点的取值就依赖于 b b b 了。

如果有很多点,我们可以按照询问的叶子的顺序,每次找到这个叶子的祖先第一个取值还未被确定的点(即这个点的取值不依赖与任意一个叶子),然后如果是 and,则该叶子取值为 1 1 1,为 or 则为 0 0 0

需要注意的是如果是最后一个叶子,那么对应的祖先一定是根结点,而此时根结点的取值依赖与最后一个叶子的取值,所以最后一个叶子取值为 1 1 1

这样做的复杂度为 O ( n ) O(n) O(n),应为每一个点都只会被找两次。

#include <bits/stdc++.h>
using namespace std;
#define Min(_A, _B) (_A < _B ? _A : _B)
#define Max(_A, _B) (_A > _B ? _A : _B)
int F()
{int x = 0; char ch; bool minus = 0;while(ch = getchar(), (ch > '9' || ch < '0') && ch != '-');ch == '-' ? minus = 1 : x = ch - '0';while(ch = getchar(), ch <= '9' && ch >= '0') x = x * 10 + ch - '0';return minus ? -x : x;
}const int MaxN = 500010;
int Next[MaxN << 2], Point[MaxN << 1], To[MaxN << 2], q, P[MaxN << 1];
void Add(int u, int v)
{Next[++q] = Point[u]; Point[u] = q; To[q] = v;Next[++q] = Point[v]; Point[v] = q; To[q] = u;
}
int N, f[MaxN << 1][2], p[MaxN << 1][2], w[MaxN << 1], l[MaxN << 1], r[MaxN << 1], fa[MaxN << 1];
void dfs(int u, int from)
{fa[u] = from;for(int j = Point[u]; j; j = Next[j]) if(To[j] != from){if(!l[u]) l[u] = To[j]; else r[u] = To[j];dfs(To[j], u);}
}
int ans[MaxN], pre[MaxN], Q[MaxN << 1], cnt;
bool vis[MaxN];
int find(int u){ return u == pre[u] ? u : pre[u] = find(pre[u]); }
int main()
{scanf("%d", &N);for(int i = 1; i < N; ++i) scanf("%d", &w[i + N]);for(int i = 1; i <= 2 * N - 2; ++i) Add(F(), F());for(int i = 1; i <= N; ++i) P[i] = F();dfs(N + 1, 0);for(int i = 1; i <= N; ++i) pre[i] = i;for(int i = 1; i <= N; ++i){vis[P[i]] = 1;int t = P[i];while(fa[t] && vis[l[fa[t]]] && vis[r[fa[t]]]) {t = fa[t];vis[t] = 1;}if(fa[t]) ans[P[i]] = !w[fa[t]];else ans[P[i]] = 1;}for(int i = 1; i <= N; ++i) printf("%d", ans[i]);return 0;
}

T3 监控中心

认真分析题目发现,题目其实是给定一张图,图中的每个点要么属于 A A A,要么属于 B B B,告诉你哪些边连接着不同集合中的元素,求 ∣ A ∣ |A| A

首先看子任务 1 1 1,一条链。我们发现如果有连续的几个 A A A 中的元素被夹在 B B B 中,那么我们可以利用后缀和的方式,将两个边界处的元素的位置相减,得到被夹在中间的 A A A 中元素的个数。

再来看子任务 2 , 3 2,3 2,3,一棵树。道理和子任务 1 1 1 是类似的,我们只需要将后缀和改为子树和,然后也可以利用加减来得出元素的个数。需要注意你求的集合是否为 A A A

子任务 4 4 4,一张图。找出任意的生成树,按照树来做。因为图给出的边有很多是没有价值的,多余的。

#include <bits/stdc++.h>
using namespace std;
int F()
{int x = 0; char ch; bool minus = 0;while(ch = getchar(), (ch > '9' || ch < '0') && ch != '-');ch == '-' ? minus = 1 : x = ch - '0';while(ch = getchar(), ch <= '9' && ch >= '0') x = x * 10 + ch - '0';return minus ? -x : x;
}
#define Abs(_A) (_A > 0 ? _A : -(_A))
const int MaxN = 1000010, MaxM = 2500010;
int n, m, Q[10000010];
struct Edge { int u, v; } e[MaxM];
int Next[MaxN << 1], To[MaxN << 1], Point[MaxN], q;
bool vis[MaxM];
void Add(int u, int v)
{Next[++q] = Point[u]; Point[u] = q; To[q] = v;Next[++q] = Point[v]; Point[v] = q; To[q] = u;
}
int l[MaxN], sum[MaxN], dfn_index;
void dfs(int u, int from)
{l[u] = ++dfn_index; ++sum[u];for(int j = Point[u]; j; j = Next[j]) if(To[j] != from){dfs(To[j], u);sum[u] += sum[To[j]];}
}
int pre[MaxN];
int find(int u){ return u == pre[u] ? u : pre[u] = find(pre[u]); }
int main()
{scanf("%d %d", &n, &m);for(int i = 1; i <= m; ++i) e[i] = (Edge){F(), F()};for(int i = 1; i <= n; ++i) pre[i] = i;for(Edge *i = e + 1; i <= e + m; ++i){int X = find(i->u), Y = find(i->v);if(X != Y){pre[X] = Y;Add(i->u, i->v);vis[i - e] = 1;}}dfs(1, 0);int q;scanf("%d", &q);for(int i = 1; i <= q; ++i){int c, tot = 0, pos = 0, tmp = 2147483647; scanf("%d", &c);for(int j = 1; j <= c; ++j) {scanf("%d", &Q[j]);if(!vis[Abs(Q[j])]) continue;if(l[e[Abs(Q[j])].u] < tmp) tmp = l[e[Abs(Q[j])].u], pos = e[Abs(Q[j])].u;if(l[e[Abs(Q[j])].v] < tmp) tmp = l[e[Abs(Q[j])].v], pos = e[Abs(Q[j])].v;}bool flag = 1;for(int j = 1; j <= c; ++j){int u, v;if(!vis[Abs(Q[j])]) continue;if(Q[j] > 0) u = e[Q[j]].u, v = e[Q[j]].v;if(Q[j] < 0) u = e[-Q[j]].v, v = e[-Q[j]].u;if(pos == v) flag = 0;if(l[u] < l[v]) tot -= sum[v];else tot += sum[u];}if(!flag) tot = n - tot;printf("%d\n", Abs(tot));}return 0;
}

T4 法师

目测一道计算几何题,Div.2 全场无人 AC,而且还没部分分(有我应该也写不出来)


rank 20- 应该是有件衣服过冬了。

这篇关于CodePlus 第五次网络赛 掐指会算的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/673125

相关文章

Linux系统配置NAT网络模式的详细步骤(附图文)

《Linux系统配置NAT网络模式的详细步骤(附图文)》本文详细指导如何在VMware环境下配置NAT网络模式,包括设置主机和虚拟机的IP地址、网关,以及针对Linux和Windows系统的具体步骤,... 目录一、配置NAT网络模式二、设置虚拟机交换机网关2.1 打开虚拟机2.2 管理员授权2.3 设置子

揭秘Python Socket网络编程的7种硬核用法

《揭秘PythonSocket网络编程的7种硬核用法》Socket不仅能做聊天室,还能干一大堆硬核操作,这篇文章就带大家看看Python网络编程的7种超实用玩法,感兴趣的小伙伴可以跟随小编一起... 目录1.端口扫描器:探测开放端口2.简易 HTTP 服务器:10 秒搭个网页3.局域网游戏:多人联机对战4.

SpringBoot使用OkHttp完成高效网络请求详解

《SpringBoot使用OkHttp完成高效网络请求详解》OkHttp是一个高效的HTTP客户端,支持同步和异步请求,且具备自动处理cookie、缓存和连接池等高级功能,下面我们来看看SpringB... 目录一、OkHttp 简介二、在 Spring Boot 中集成 OkHttp三、封装 OkHttp

Linux系统之主机网络配置方式

《Linux系统之主机网络配置方式》:本文主要介绍Linux系统之主机网络配置方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、查看主机的网络参数1、查看主机名2、查看IP地址3、查看网关4、查看DNS二、配置网卡1、修改网卡配置文件2、nmcli工具【通用

使用Python高效获取网络数据的操作指南

《使用Python高效获取网络数据的操作指南》网络爬虫是一种自动化程序,用于访问和提取网站上的数据,Python是进行网络爬虫开发的理想语言,拥有丰富的库和工具,使得编写和维护爬虫变得简单高效,本文将... 目录网络爬虫的基本概念常用库介绍安装库Requests和BeautifulSoup爬虫开发发送请求解

如何通过海康威视设备网络SDK进行Java二次开发摄像头车牌识别详解

《如何通过海康威视设备网络SDK进行Java二次开发摄像头车牌识别详解》:本文主要介绍如何通过海康威视设备网络SDK进行Java二次开发摄像头车牌识别的相关资料,描述了如何使用海康威视设备网络SD... 目录前言开发流程问题和解决方案dll库加载不到的问题老旧版本sdk不兼容的问题关键实现流程总结前言作为

SSID究竟是什么? WiFi网络名称及工作方式解析

《SSID究竟是什么?WiFi网络名称及工作方式解析》SID可以看作是无线网络的名称,类似于有线网络中的网络名称或者路由器的名称,在无线网络中,设备通过SSID来识别和连接到特定的无线网络... 当提到 Wi-Fi 网络时,就避不开「SSID」这个术语。简单来说,SSID 就是 Wi-Fi 网络的名称。比如

Java实现任务管理器性能网络监控数据的方法详解

《Java实现任务管理器性能网络监控数据的方法详解》在现代操作系统中,任务管理器是一个非常重要的工具,用于监控和管理计算机的运行状态,包括CPU使用率、内存占用等,对于开发者和系统管理员来说,了解这些... 目录引言一、背景知识二、准备工作1. Maven依赖2. Gradle依赖三、代码实现四、代码详解五

Linux 网络编程 --- 应用层

一、自定义协议和序列化反序列化 代码: 序列化反序列化实现网络版本计算器 二、HTTP协议 1、谈两个简单的预备知识 https://www.baidu.com/ --- 域名 --- 域名解析 --- IP地址 http的端口号为80端口,https的端口号为443 url为统一资源定位符。CSDNhttps://mp.csdn.net/mp_blog/creation/editor

ASIO网络调试助手之一:简介

多年前,写过几篇《Boost.Asio C++网络编程》的学习文章,一直没机会实践。最近项目中用到了Asio,于是抽空写了个网络调试助手。 开发环境: Win10 Qt5.12.6 + Asio(standalone) + spdlog 支持协议: UDP + TCP Client + TCP Server 独立的Asio(http://www.think-async.com)只包含了头文件,不依