Educational Codeforces Round 169 (Rated for Div. 2)

news2024/9/21 23:41:03

前言

       电脑显示屏一闪一闪地感觉要拿去修了,比赛时重启了好几次。

        手速场,E 题没学过 Sprague-Grundy 吃了亏,好在前四题都一发过才不至于掉分。

        Standings:1214

        题目链接:Dashboard - Educational Codeforces Round 169 (Rated for Div. 2) - Codeforces

A. Closest Point

        题意:

        给一个集合表示数轴上的一些点,你需要在数轴上加入一个不同于集合内任何元素的整数点,使得这个点是所有集合内的点最近点,也就是这个点到所有点的路上不能有其他点。

        思路:

        显然只有 n = 2 时且两个点不是相邻的整数才有解。

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

int T,n,a[105];

int main()
{
	scanf("%d",&T);
	while (T --)
	{
		scanf("%d",&n);
		for (int i = 1;i <= n;++ i) scanf("%d",&a[i]);
		sort(a + 1,a + n + 1);
		int flag = 1;
		for (int i = 2;i <= n;++ i)
			if(a[i] - a[i - 1] <= 1)
			{
				flag = 0;
				break;
			}
		if(n > 2) flag = 0;
		if(flag) printf("YES\n");
		else printf("NO\n"); 
	}
	return 0;
}

B. Game with Doors

        题意:

        有 100 个房间排成一排,相邻房间有门连接,告诉你两个人可能所在的房间区间(是一段连续的子区间),求最少锁上多少间房门能让这两个人所在的房间不能互通。

        思路:

        分类讨论即可,懒得写了。

#include<cstdio>
#include<cstring>
using namespace std;

int T,l,r,x,y;

int main()
{
	scanf("%d",&T);
	while (T --)
	{
		scanf("%d%d%d%d",&l,&r,&x,&y);
		int tmp,ans;
		if(l > x || l == x && r < y) tmp = l,l = x,x = tmp,tmp = r,r = y,y = tmp;
		if(r < x) ans = 1;
		else if(r >= x && y >= r) ans = (r - x) + (y > r) + (l < x);
		else if(r >= x && y < r) ans = (y - x) + (r > y) + (l < x);
		printf("%d\n",ans);
	}
	return 0;
}

C. Splitting Items

        题意:

        给一串数字作为分值,两个人轮流取,总得分分别记作 A 和 B,你可以对原数列进行操作,给任意数量的数字增加一个数,增加的总和不能超过 k ,求 A - B 的最小值。

        思路:

        显然贪心,从大到小排序后,A 肯定会取奇数位上的数字,尽可能地增加偶数位上的数字使 B 更大,但是不能超过前一位 A 取的数,否则这个数就会被 A 拿走。

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

#define N 200005

int T,n,k,a[N];
long long ans;

int cmp(int x,int y) { return x > y ; }

int main()
{
	scanf("%d",&T);
	while (T --)
	{
		scanf("%d%d",&n,&k);
		for (int i = 1;i <= n;++ i) scanf("%d",&a[i]);
		sort(a + 1,a + n + 1,cmp);
		ans = 0ll;
		for (int i = 1;i <= n;++ i)
		{
			if(i & 1) ans += 1ll * a[i];
			else
			{
				int now = a[i - 1] - a[i];
				if(k >= now) a[i] = a[i - 1],k -= now;
				else a[i] += k,k = 0;
				ans -= 1ll * a[i];
			}
		}
		printf("%lld\n",ans);
	}
	return 0;
}

D. Colored Portals

        题意:

        给 n 个城市,城市 i 和 j 之间的距离是 |i - j| ,每个城市有两种传送门,可以通过相同的传送门在城市之间穿梭,有若干个询问找出城市 x 到城市 y 的最短距离。

        思路:

        显然要么直达,要么只中转一次,要么无法到达。

        中转的情况分情况讨论二分查找使得总距离最短的那个城市即可。

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;

#define N 200005

int T,n,q,ans,a[6][N],c[6],id[N],inv[6];
char s[5];

int min(int x,int y) { return x < y ? x : y ; }

int find(int k,int x,int y)
{
	int l,r,mid,now,tmp;
	l = 1,r = c[k],now = 0;
	while (l <= r)
	{
		mid = (l + r) >> 1;
		if(a[k][mid] > x) now = a[k][mid],r = mid - 1;
		else l = mid + 1;
	}
	if(x < now && now < y) return y - x ;
	l = 1,r = c[k],now = 0,tmp = 1e9;
	while (l <= r)
	{
		mid = (l + r) >> 1;
		if(a[k][mid] < x) now = a[k][mid],l = mid + 1;
		else r = mid - 1;
	}
	if(now) tmp = min(tmp,x - now + y - now);
	l = 1,r = c[k],now = 0;
	while (l <= r)
	{
		mid = (l + r) >> 1;
		if(a[k][mid] > y) now = a[k][mid],r = mid - 1;
		else l = mid + 1;
	}
	if(now) tmp = min(tmp,now - x + now - y);
	return tmp;
}

int main()
{
	for (int i = 0;i < 6;++ i) inv[i] = 5 - i;
	scanf("%d",&T);
	while (T --)
	{
		memset(c,0,sizeof c);
		scanf("%d%d",&n,&q);
		for (int i = 1;i <= n;++ i)
		{
			cin >> s + 1;
			if(s[1] == 'B' && s[2] == 'G') a[0][++ c[0]] = i,id[i] = 0;
			if(s[1] == 'B' && s[2] == 'R') a[1][++ c[1]] = i,id[i] = 1;
			if(s[1] == 'B' && s[2] == 'Y') a[2][++ c[2]] = i,id[i] = 2;
			if(s[1] == 'G' && s[2] == 'R') a[3][++ c[3]] = i,id[i] = 3;
			if(s[1] == 'G' && s[2] == 'Y') a[4][++ c[4]] = i,id[i] = 4;
			if(s[1] == 'R' && s[2] == 'Y') a[5][++ c[5]] = i,id[i] = 5;
		}
		while (q --)
		{
			int x,y,tmp,ix,iy;
			scanf("%d%d",&x,&y),ans = 1e9;
			if(x > y) tmp = x,x = y,y = tmp;
			ix = id[x],iy = id[y];
			if(ix == inv[iy])
			{
				for (int i = 0;i < 6;++ i)
				{
					if(i == ix || i == iy) continue;
					ans = min(ans,find(i,x,y));
				}
			}
			else ans = y - x;
			if(ans == 1e9) printf("-1\n");
			else printf("%d\n",ans);
		}
	}
	return 0;
}

E. Not a Nim Problem

        题意:

        常规的取石子游戏变形,限制就是只能取和当前堆数互质的数目。

        思路:

        经典的博弈论题目,要用到 Sprague-Grundy 函数,比赛后恶补了一下,发现还挺有意思。

        感觉瞪眼法很难看出有什么规律,打个表就很显而易见了:

        1. sg(1) = 1

        2. 若 x 为偶数,则 sg(x) = 0

        3. 其他情况,设 x 的最小质因子为 p ,则 sg(x) = p 在质数中从小到大的排位(记作num)

        证明:

        1 和 2 是显然的,这里我们主要考虑 3 ,用数学归纳法证明。

        假设 1 ~ x - 1 都满足上述条件,考虑 sg(x) 的值,要证 x 的后继中有 0 ~ num - 1 但是不能有num。

        对于 x ,我们肯定可以取 1 个或者 x - 1 个石子,这样后继就是 sg(x - 1) 和 sg(1) ,分别对应 0 和 1。接着,肯定也可以取到剩下小于 p 个石子,即 2 ~ p - 1,那么后继就是 sg(2) , sg(3), ... , sg(p - 1),根据前面的条件都满足,这些后继肯定包含了 2 ~ num - 1 的值。综上,后继中一定有 0 ~ num - 1。

        那么后继能不能有 num 呢?反证。假设有,那么意思是后继中也有某一堆石子数,满足其最小质因子为 p ,这样这堆就和原来的互质了,违背题意。

        因此,sg(x) = num 。

#include<cstdio>
#include<cstring>
using namespace std;

#define N 10000007

int T,n,check[N],prime[N],p[N],num[N],cnt,tmp,ans;

void ola()
{
	check[1] = 1,cnt = 0;
	for (int i = 2;i < N;++ i)
	{
		if(!check[i]) prime[++ cnt] = i,p[i] = i;
		for (int j = 1;j <= cnt;++ j)
		{
			if(i * prime[j] >= N) break;
			check[i * prime[j]] = 1,p[i * prime[j]] = prime[j];
			if(!(i % prime[j])) break;
		}
	}
	for (int i = 1;i <= cnt;++ i) num[prime[i]] = i;
	return;
}

int main()
{
	ola();
	scanf("%d",&T);
	while (T --)
	{
		scanf("%d",&n),ans = 0;
		for (int i = 1,x;i <= n;++ i)
		{
			scanf("%d",&x);
			if(x == 1) tmp = 1;
			else if(!(x & 1)) tmp = 0;
			else tmp = num[p[x]];
			ans ^= tmp;
		}
		if(ans) printf("Alice\n");
		else printf("Bob\n");
	}
	return 0;
}

F. Make a Palindrome

        题意:

        给一个长度为 n 的整数序列 a ,定义 f(b) 表示使得序列 b 回文的最少操作数,每次操作可以选择序列的任意一端,要么合并这一端的两个数;要么让端点的这个数拆分成两个数,使得这两个数之和与原来相等。计算序列 a 的所有子序列的 f 值之和。

        思路:

        首先不难发现,合并和拆分操作的意义是一样的,即当你选择一次合并操作的时候,也一定可以使用一次拆分操作满足相同的回文要求,只是序列中的数字不一样而已。

        我们考虑某个序列 p ,我们用最小的操作使序列两端的数字之和相等,这样的条件是序列的某个前缀和与后缀和相等,然后我们只用合并操作就可以达到这一条件。那么得到剩下的不合法序列就是一个子序列,我们可以用分治考虑它。

        我们记某一段区间 [l,r] 的前缀和为 s ,考虑它需要的操作数:

        找出最大的子区间 [x,y] 使得 s_{x - 1} - s_{l-1} = s_y - s_r , 即 s_r+s_{l-1} = s_y + s_{x-1},因此我们发现所有 s_r+s_{l-1} 相等的区间都是一组,并且一定是包含关系(因为前缀和是单调的,一个增加另一个必须减少,即区间左端点右移的时候,区间右端点一定左移)。于是每两个相邻区间都会有一个操作数的差值,我们先统计假设所有组的区间都以最大长度的那个区间计算时需要的操作数,再减去所有多计算的操作数即可。

#include<cstdio>
#include<cstring>
#include<map>
using namespace std;

#define N 2005

int T,n,a[N],pre[N],ans;
map< int, int > mpl,mpr;

int main()
{
	scanf("%d",&T);
	while (T --)
	{
		scanf("%d",&n),pre[0] = ans = 0;
		for (int i = 1;i <= n;++ i) scanf("%d",&a[i]),pre[i] = pre[i - 1] + a[i];
		map< int, int > mp;
		for (int i = 0;i < n;++ i)
			for (int j = i;j <= n;++ j)
				ans += j - i - 1,++ mp[pre[i] + pre[j]];
		for (auto [x,y] : mp) ans -= y * (y - 1);
        for (int i = 0;i <= n;++ i) ans += mp[2 * pre[i]]; 
		printf("%d\n",ans);
	}
	return 0;
}

总结

        这套比赛主要是博弈论的 E 题没有学过吃了亏,但是这是无关紧要的,遇到不会的知识点时去填坑就好了,主要还是像 F 这种难度的计数题比较难想,需要大量做题大量思考来引起质变。

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

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

相关文章

shell脚本中$0 $1 $# $@ $* $? $$ 的各种符号意义详解

文章目录 一、概述1.1、普通字符1.2、元字符 二、转义字符$2.1、实例12.2、实例22.3、实例32.4、实例42.5、实例5 三、linux命令执行返回值$?说明 一、概述 shell中有两类字符&#xff1a;普通字符、元字符。 1.1、普通字符 在Shell中除了本身的字面意思外没有其他特殊意义…

设计模式-结构性模式-桥接模式

1.桥接模式定义 桥接模式就是将抽象部分与他的实现部分分离&#xff0c;使他们都可以独立的变化&#xff1b; 桥接模式用一种巧妙地方式处理多层继承存在的问题&#xff0c;用抽象关联来取代传统的多层继承&#xff0c;将类之间的静态继承关系转变为动态的组合关系&#xff0c;…

26个希腊字母写法和读音

瞧&#xff0c;在许多时候都会用到这些希腊字母&#xff0c;但不认识更不知道怎么读&#xff0c;so 记录一下便于查阅 26个希腊字母写法和读音 大写小写中文名英文注音意义Aα阿尔法Alpha角度;系数Bβ贝塔Beta磁通系数;角度;系数「γ伽玛Gamma电导系数(小写)Δδ德尔塔Delta变…

ES之二:centos7安装kibana和IK分词器

目录 一、Kibana介绍二、Kibana安装1、注意elasticsearch 和 kibana使用同一个版本2、更改配置3、kibana使用 三、Kibana安装1. 解压ik分词器2. 重新启动ES启动报错&#xff1a; 一、Kibana介绍 Kibana是一个针对Elasticsearch的开源分析及可视化平台&#xff0c;使用Kibana可…

客户端可以访问ntp时钟源,时间却一直不同步的问题

ntp时钟源通常是通过开放123 的udp端口对外提供ntp服务的&#xff0c;udp端口的访问可以通过nc -uvz xx.xx.xx.xx 123 端口进行验证&#xff0c;验证发现ntp时钟服务的123端口是开放的&#xff0c;也没有防火墙拦截123端口&#xff0c;但为什么客户端不同步ntp时钟源呢&#xf…

鸿蒙内核源码分析(异常接管篇) | 社会很单纯,复杂的是人

为何要有异常接管? 拿小孩成长打比方&#xff0c;大人总希望孩子能健康成长&#xff0c;但在成长过程中总会遇到各种各样的问题&#xff0c;树欲静而风不止&#xff0c;成长路上有危险&#xff0c;有时是自己的问题有时是外在环境问题.就像抖音最近的流行口水歌一样&#xff…

dp的练习总结(9)

P8766 异或三角 1.由题干给出的条件可知&#xff1a; (1)1≤a,b,c≤n&#xff0c;可得上限和枚举的范围 (2)a⊕b⊕c0&#xff0c;只有当前位相同的二进制数字异或才是 0&#xff0c;所以由此可知&#xff0c;当前位 a,b,c 都选 0&#xff0c;或 a,b,c 中任意两个数选择 1。同时…

Linux jobs命令:查看和管理后台任务

目录 一、jobs命令简介二、jobs命令适用的Linux版本三、jobs命令的基本语法四、jobs命令的常用选项或参数五、jobs命令实例5.1 显示当前shell中的后台作业将命令放到后台查看后台作业状态将后台作业带到前台 5.2 显示后台作业的进程号5.3 显示已停止的后台作业5.4 显示上次shel…

it程序员常用的技术社区网站有哪些

it程序员常用的技术社区网站有哪些??作为程序员&#xff0c;选择好合适的开发社区对提高自己的编程能力会有很大的帮助&#xff0c;技术人员经常会在各种技术交流社区游逛。优秀的实时开发社区确实能帮你积累不少开发经验技术教程 _ 网址大全 _ 博科趣 - 第1页技术教程网站,技…

cuda性能分析工具: nsight systems

安装 1. 安装nsys&#xff0c; nsys可以用命令行生成性能分析报告&#xff0c;参考&#xff1a; nsys profile 2. 安装Nsight Systems可视化工具NVIDIA Nsight Systems | NVIDIA 开发者 使用方法 1. 找一个可执行的cuda程序&#xff0c;编译成可执行文件&#xff0c;比如m…

14-17岁未成年如何办理能一直用的手机卡?

14-17岁未成年如何办理能一直用的手机卡&#xff1f; 有些姐妹要去外面上学&#xff0c;都想要一张属于自己的手机卡。 但是因为反诈的原因&#xff0c;对于手机卡的申领特别严格。 很多不满18岁的人能申领的卡&#xff0c;都是物联卡或者纯流量卡&#xff0c;只能上网&#x…

pytorch深度学习基础 6(简单的参数估计学习2)

上一节我们建立了一个简单的模型进行分析散点图&#xff0c;利用均方差来实现损失函数的计算&#xff0c;但是并没有计算出具体的参数值&#xff0c;这次我们来计算损失函数的损失值以及不断减小损失值&#xff0c;计算出最优的参数&#xff0c;代码原理非常简单大家可以自行理…

TOMCAT-企业级WEB应用服务器

一 WEB技术 1.1 HTTP协议和B/S 结构 HTTP&#xff08;HyperText Transfer Protocol&#xff09;协议即超文本传输协议&#xff0c;是用于在万维网&#xff08;WWW&#xff09;上传输超文本内容的基础协议。 一、HTTP 协议的特点 1、简单快速 客户向服务器请求服务时&#…

八股(3)——计网

八股&#xff08;3&#xff09;——计网 3. 计算机基础3.1 计算机网络OSI 七层模型是什么&#xff1f;每一层的作用是什么&#xff1f;TCP/IP 四层模型是什么&#xff1f;每一层的作用是什么&#xff1f;1. 应用层&#xff08;Application layer&#xff09;2. 传输层&#xff…

【iOS安全】iPhone8 iOS14.4.2 越狱教程

环境配置 iPhone 8&#xff1a; 固件版本 iOS 14.4.2 (18D70) 产品类型 iPhone10,1 (A1906) 销售型号 MQ862J/A MacBook Pro&#xff1a; macOS 10.15.7 装有CheckRa1n beta 0.12.4 概述 尝试了几个版本的unc0ver和Taurine&#xff0c;发现都不好使 unc0ver显示unsupported…

如何实现一棵AVL树

目录 1.什么是AVL树&#xff1f; 2.AVL树的实现 2.1AVL树结点的定义 2.2AVL树的插入 2.2.1插入的步骤 2.2.2插入情况分析 2.2.3旋转操作的分析 2.3AVL树的查找 3.AVL树的验证 4.AVL树的性能分析 1.什么是AVL树&#xff1f; AVL树其实就是一棵加了限制条件的二叉搜索树…

day38.动态规划+MySql数据库复习

844.比较含退格的字符串 给定 s 和 t 两个字符串&#xff0c;当它们分别被输入到空白的文本编辑器后&#xff0c;如果两者相等&#xff0c;返回 true 。# 代表退格字符。 注意&#xff1a;如果对空文本输入退格字符&#xff0c;文本继续为空 思路:定义两个栈&#xff0c;将字符…

集合及数据结构第九节————树和二叉树

系列文章目录 集合及数据结构第九节————树和二叉树 树和二叉树 树型结构的概念树的概念树的表示形式&#xff08;了解&#xff09;树的应用二叉树的概念两种特殊的二叉树二叉树的性质二叉树的性质练习二叉树的存储二叉树的遍历二叉树的基本操作二叉树相关练习题 文章目录…

flutter 中 ssl 双向证书校验

SSL 证书&#xff1a; 在处理 https 请求的时候&#xff0c;通常可以使用 中间人攻击的方式 获取 https 请求以及响应参数。应为通常我们是 SSL 单向认证&#xff0c;服务器并没有验证我们的客户端的证书。为了防止这种中间人攻击的情况。我么可以通过 ssl 双向认证的方式。即…

Leetcode JAVA刷刷站(91)解码方法

一、题目概述 二、思路方向 这个问题是一个典型的动态规划问题&#xff0c;其中我们可以使用一个数组来存储到达每个位置时的解码方法的总数。 我们定义一个数组 dp&#xff0c;其中 dp[i] 表示字符串 s 的前 i 个字符&#xff08;从索引 0 到 i-1&#xff09;的解码方法总数。…