atcoder350,351,352,353,354,355期部分题解

声明:有些题感觉已经说到很明白了,就先不写代码了,有空会补上

目录

350D: new friend

350E: toward 0

351D:Grid and Magnet

352D:permutation  subsequence

353C: sigma problem

353D: another sigma problem

354C: atcoder magics

355C: bingo2

355D: intersecting intervals 

附加题:火烧赤壁


希望读者可以有所收获 

        

        

350D: new friend

就是问你,最终有多少对这种关系:x和y是朋友,y和z是朋友,但是x和z不是朋友。你也把这种关系理解成y是中介方,但是我们要明白一点,x和y和z一定是在同一个联通块中。所以选点一定就是在联通块中选择。

也就是说:在同一个联通块中,如果x和y是朋友关系,那么它们不满足题意;如果x和y不是朋友关系,那么它们就满足题意。所以我们只需要找所有联通块中有多少对新朋友,加起来,然后减去原来的朋友数即可。

(为什么我会想到联通块呢?因为在我们做题的时候,尤其是图论,一定要尽量把题给抽象一下,你才能想到考察的知识点)

最后,要求联通块中的新朋友对数,就需要求联通块中的点数,我们可以dfs跑联通块,然后返回这个联通块中的点数,同时给遍历过的点打上标签,然后去跑别的联通块;我们也可以直接并查集来做,维护祖宗节点的cnt值,存放该集合的点数。

        

        

350E: toward 0

题意:给一个N,然后每轮有两种操作,一个是花费x变成[N/A],另一个是花费y变成[N/b],b等概率取1,2,3,4,5,6。 

分析:一道期望dp,感觉和概率dp差不多,大致思路都是dp[起始状态]=初始概率或者初始期望,然后找每轮之间的关系进行转移,一直dp到最终状态就行了。

我们先找每轮之间的关系:

我们设置f[N]表示N变成0的期望花费,初始f[0]=0

f[N]=Y+(f[N/6]+f[N/5]+f[N/4]+f[N/3]+f[N/2]+f[N/1])/6

修改一下变成:f[N]=6/5*Y+(f[N/6]+f[N/5]+f[N/4]+f[N/3]+f[N/2])/5

所以:f[N]=min(X+f[N/A],6/5*Y+(f[N/6]+f[N/5]+f[N/4]+f[N/3]+f[N/2])/5)

接下来就是转移就完事了,明显借助dfs来完成转移更加方便。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
unordered_map<ll,double>mp;
ll N,A,X,Y;
double f(ll x){
	if(x==0)return 0; //初始值
	if(mp.count(x))return mp[x]; //记忆化
	double ret2=0,ret1=f(x/A)+X;
	for(int i=2;i<=6;i++)ret2+=f(x/i);
	ret2=(ret2+6*Y)/5;
	return mp[x]=min(ret1,ret2);
}
int main(){
	cin>>N>>A>>X>>Y;
	printf("%.9f",f(N));
}

代码为什么要用double呢?因为存在性质:[[N/a]/b]=[N/ab],所以要保持精度。 

        

        

351D:Grid and Magnet

 题意:HxW的网格,' . '代表可以走,' # '代表有磁铁,会吸住上下左右的格子,导致不能再移动,要求输出从某一个点能走的最多格子。

考的还是联通块,我们可以把每个磁铁周围会被吸住的格子打上标记,然后我们去搜图中的每一个联通块,并统计每个联通块的块数,最后输出最大的块数即可。

        

        

352D:permutation  subsequence

题意:有一个序列1~n的某一排序,我们要在此排序中找到长度最小的包含长度为k的任意自然数段。

我这里强调一下这种自然数某一排序题的常见思路:就是分析pos数组,pos数组就是每个数的位置信息。

比如:10 1 6 8 7 2 5 9 3 4   构造pos数组如下:

数组:2 6 9 10 7 3 5 4 8 1(表示每个1~n的位置信息)

我们开始考虑1~5的最小符合题意的长度:处理2 6 9 10 7即可,max-min=8,说明长度为8

考虑2~6:max-min=7

考虑3~7:max-min=7

考虑4~8:max-min=5

考虑5~9:max-min=5

考虑6~10:max-min=7

所以答案就是5

也就是我们只需要求出每个区间的极差即可,使用滑动窗口就可以了。

        

        

353C: sigma problem

首先要理解这个玩意:

它意思就是

    for(int i=1;i<=n-1;i++)
	for(int j=i+1;j<=n;j++){
		ans+=f(a[i],a[j]);
	}

但是我们肯定不能直接这样做,因为太慢了,那么我们就要找规律了:

那么最直接的想法就是“变加为乘”,以此来加速。

我们不难发现:全部的相加过程中:

a[1]+a[2]   a[1]+a[3]   a[1]+a[4]……a[1]+a[n]

a[2]+a[3]   a[2]+a[4]……a[2]+a[n]

……

也就是说如果我们先不考虑取模的情况时,每个数a[i]都会被加n-1次

然后我们再考虑取模的情况:

这里如果没有发现a[i]<10^8这个细节的话,估计就很难做出来了,如何使用这个条件呢?

我们会发现a[i]+a[j]在mod10^8的过程中最多也就是减去了一次10^8,所以我们在把所有的a[i]+a[j]大于10^8的个数找出来,然后减去10^8就行了。

#include <bits/stdc++.h>
using namespace std;
int a[300000];
int mod=100000000;
int main(){
	int n;cin>>n;
	long long ans=0;
	for(int i=0;i<n;i++){
		cin>>a[i];ans+=a[i]*(n-1ll);
	}
	sort(a,a+n);
	for(int i=0;i<n;i++){
		ans-=mod*1ll*(a+n-lower_bound(a+1+i,a+n,mod-a[i]));//另外一个数一定比当前的数更大,所以从a+1+i开始找
	}
	cout<<ans<<'\n';
}

        

        

353D: another sigma problem

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll mod=998244353;
ll suf[200005],a[200005];
ll get(ll x){
	ll ans=1;
	while(x)x/=10,ans*=10;
	return ans;
}
int main(){
	int n;cin>>n;
	for(int i=1;i<=n;i++)cin>>a[i];
	ll ans=0;
	for(int i=n;i>=1;i--){
		suf[i]=(suf[i+1]+get(a[i]))%mod; //每个数要乘的倍率的和(后缀和)
	}
	for(int i=1;i<=n;i++){
		ans+=a[i]*(i-1)%mod;//前半部分的贡献
		ans%=mod;
		ans+=suf[i+1]*a[i]%mod;//后半部分的贡献
		ans%=mod;
	}
	cout<<ans<<'\n';
}

        

        

354C: atcoder magics

 

题意:有N张卡片,每张卡片上有A和C两个数,分别表示力量和花费,我们可以进行操作:

选择两个卡片,如果A1>A2,C1<C2,我们就丢掉2卡片。问我们最终可以剩下哪些卡片?

做这种题的一个直觉就是排序:如果我们按照A从大到小排好序后,就不用再考虑A了,只需要考虑C。如果当前的卡片C值比前面的卡片的C值都小,那就留下他,否则就丢掉这个卡片。

#include <bits/stdc++.h>
using namespace std;
struct card{
	int val,cost,id;
}a[200005];
bool cmp(card x,card y){
	return x.val>y.val;
}
int main(){
	int n;cin>>n;
	for(int i=1;i<=n;i++){
		int val,cost;
		cin>>val>>cost;
		a[i]={val,cost,i};
	}
	sort(a+1,a+1+n,cmp);
	int minn=2e9;
	vector<int> ans;
	for(int i=1;i<=n;i++){
		if(a[i].cost<minn){
			ans.push_back(a[i].id);
			minn=a[i].cost;
		}
	}
	sort(ans.begin(),ans.end());
	cout<<ans.size()<<'\n';
	for(auto i:ans){
		cout<<i<<' ';
	}
	return 0;
}

        

        

355C: bingo2

题意:有一个N*N的网格,依次填入1,2,3,4……n^2(如图),然后一共有T轮,每轮都会填一个数,问至少几轮后才有一列或者一行,或者一个对角线被填充?

考察的就是如何用vis表示一个对角线,不会的回去看看CSDN中的八皇后问题,填入一个就vis++,然后检查对应的行,列,对角线,看看什么时候可以满足题意。

        

        

355D: intersecting intervals 

 

题意:有n个区间,问你一共有多少对区间相交?

先拆开分析:

1开始 7开始 3开始

5结束 8结束 7结束

我们排序:

1开始

3开始

5结束

7开始

7结束

8结束

我们要统计每个区间开始出现的时候,已经有多少个区间存在了,那么此时就会增加多少个相交区间,也就是我们要关心目前有多少个区间往后面走,当开始出现一个区间时候cnt++,当开始减少一个区间时候cnt--

排序的时候注意相同时间开始在前,结束在后(因为在某一点都同时有开始和结束也算相交)

1开始  cnt=1

3开始  cnt=2  ans=1

5结束  cnt=1  

7开始  cnt=2  ans=2

7结束  cnt=1

8结束  cnt=0

再来一个样例

1开始  cnt=1

2开始  cnt=2  ans=1

3开始  cnt=3  ans=3

4结束  cnt=2

5结束  cnt=1

6结束  cnt=0

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
struct node{
	int v,op; //op=1为结束,op=0为开始
};
vector<node>ve;
bool cmp(node x,node y){
	if(x.v==y.v)return x.op<y.op;//先返回起点再返回终点
	return x.v<y.v;
}
int main(){
	int n;cin>>n;
	for(int i=1;i<=n;i++){
		int l,r;cin>>l>>r;
		ve.push_back({l,0});
		ve.push_back({r,1});
	}
	sort(ve.begin(),ve.end(),cmp);
	int cnt=0;ll ans=0;
	for(int i=0;i<ve.size();i++){
		int v=ve[i].v,op=ve[i].op;
		if(op==0)ans+=cnt,cnt++;
		else cnt--;
	}
	cout<<ans<<'\n';
	return 0;
}

看完这题,建议再看一道很像的题。

        

        

附加题:火烧赤壁

 

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e4+10;
ll ans;
int n;
struct node{ll x;ll y;}e[N];
bool cmp(node a,node b){
	if(a.x==b.x)return a.y<b.y;
	return a.x<b.x; 
}
int main(){
	cin>>n;ll a,b;
	for(int i=1;i<=n;i++){
		scanf("%lld%lld",&a,&b);
		e[i].x=a;e[i].y=b-1;
	}
	sort(e+1,e+1+n,cmp);
	ll end=e[1].y;
	ans+=e[1].y-e[1].x+1;
	for(int i=2;i<=n;i++){
		if(end>=e[i].x){
			if(end>=e[i].y)continue;
			ans+=e[i].y-end;
			end=e[i].y;
		}
		else {
			ans+=e[i].y-e[i].x+1;
			end=e[i].y;	
		}
	}
	cout<<ans;
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

一文读懂存内计算与近存计算的分类与应用

存内计算与近存计算-基础理论及分类 技术基础知识和分类 "近存计算"与"存内计算"易混淆&#xff0c;本章明晰其分类&#xff0c;并比较各内存驱动方法的独特优势。可计算存储器设备可作分立加速器或替代现有存储模块。我们深入剖析每种方法的利弊&#xf…

像艺术家一样工作

接下来开始翻译这本小册子 豆瓣评分还是挺高的&#xff0c;目前在国内没有看到有在售的翻译版本 书名直译的话是&#xff1a;像艺术家一样去偷 作者可能是为了制造营销话题&#xff0c;所以起了这么一个名字 但是偷这个词总归不太体面&#xff0c;所以我把书名翻译为&#…

Qos令牌桶算法:笔记0601

令牌桶 令牌&#xff1a;目前看到2种表述&#xff0c;csdn表示一个令牌代表一个字节&#xff0c;51cto是一个令牌代表一个bit。51cto上关于cisco qos算法描述多表达为一个令牌一个bit (不知道rfc上咋表达的懒得去查了&#xff0c;主打一个好读书不求甚解&#xff0c;感觉应该是…

c++学习----初识类和对象(上)

1.面向过程和面向对象初步认识 C语言是面向过程的&#xff0c;关注的是过程&#xff0c;分析出求解问题的步骤&#xff0c;通过函数调用逐步解决问题。 C是基于面向对象的&#xff0c;关注的是对象&#xff0c;将一件事情拆分成不同的对象&#xff0c;靠对象之间的交互完 成。…

rtl8723DU移植 android4.4 4418

一、 linux 的移植。 首先编译一遍确保没有问题。 将驱动拷贝到 driver/net/wireless 目录下。 使用的是&#xff1a; 改写 makefile Kconfig 去改写 8723 的makefile 设置menuconfig 使能固有的 库。 使能USB部分 ieee 部分 编译一遍 有报错。 解决&#xff1a; …

基于深度学习YOLOv8\YOLOv5的花卉识别鲜花识别检测分类系统设计

本文将介绍基于深度学习YOLOv8\YOLOv5PySide6SQLite的花卉检测与识别系统&#xff0c;该系统基于YOLOv8算法&#xff0c;并与YOLOv5版本进行比较&#xff0c;该系统不仅实现了对花卉的精准识别和分类&#xff0c;还提供了包括用户认证管理、模型快速切换及界面个性化定制在内的…

ssm汉服文化平台网站

博主介绍&#xff1a;✌程序员徐师兄、8年大厂程序员经历。全网粉丝15w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;…

【TB作品】msp430f5529单片机墨水屏,口袋板,tmp421温度,温控风扇

文章目录 一、扬声器模块介绍二、驱动介绍三、程序介绍四、全部代码下载 msp430f5529d单片机墨水屏&#xff0c;口袋板&#xff0c;tmp421温度&#xff0c;温控风扇 基本要求&#xff1a;高于20度开转&#xff0c;温度越高转速越快&#xff0c;高于40度风扇停转&#xff0c;温…

Day45 动态规划part05

LC1049最后一块石头重量II(未掌握) 未掌握分析&#xff1a;其实本题跟LC416分割等和子集类似&#xff0c;本质上题目的要求是尽量让石头分成重量相同的两堆&#xff0c;相撞之后剩下的石头最小&#xff0c;也就是01背包问题weight和value都是stones数组&#xff0c;题目可以看…

Java的JDK环境变量配置(Windows)

只写了需要配置的环境变量 注&#xff1a;从JDK1.5开始&#xff0c;配置Java环境变量时&#xff0c;不再需要配置CLASSPATH&#xff0c;只需要配置JAVA_HOME和Path 1、配置JAVA_HOME 找到自己的JDK位置&#xff0c;我这里是 C:\dev\java\jdk-17.0.119在环境变量-系统变量中&…

【已解决】Error in the HTTP2 framing layer

1.问题描述 在使用git将代码上传github的时候在最后一部push的时候遇到这个fatal 2.解决方案 由于我原先设置的origin是http协议下的&#xff0c;如下 git remote add origin https://github.com/Charlesbibi/Simple_Cloud.githttp协议下行不通不妨试一试ssh协议下&#xff…

代码随想录算法训练营 day23| ● 669. 修剪二叉搜索树 ● 108.将有序数组转换为二叉搜索树 ● 538.把二叉搜索树转换为累加树

文章目录 前言669. 修剪二叉搜索树思路方法一 递归法方法二 迭代法 108.将有序数组转换为二叉搜索树思路方法一 递归法方法二 迭代法 538.把二叉搜索树转换为累加树思路方法一方法二 总结 前言 迭代法都没看主要是669和538【538很简单】 669. 修剪二叉搜索树 思路 不用看教程…

stack学习

std::stack 类是一种容器适配器&#xff0c;它给予程序员栈的功能——特别是 FILO&#xff08;先进后出&#xff09;数据结构。该类模板用处为底层容器的包装器——只提供特定函数集合。栈从被称作栈顶的容器尾部推弹元素。 operator 赋值给容器适配器 (公开成员函数) 元素访问…

C#开发的应用升级更新服务器端工具 - 开源研究系列文章 - 个人小作品

笔者开发过一些小应用&#xff0c;然后这些应用就需要有升级更新的功能&#xff0c;但是如果每个都集成进去也行&#xff0c;但是就是得写死更新的代码了。于是就想写一个应用升级更新的管理器&#xff0c;以前看到过Github上有一个AutoUpdate.Net&#xff0c;不过它那个要集成…

openssl 常用命令demo

RSA Private Key的结构&#xff08;ASN.1&#xff09; RSAPrivateKey :: SEQUENCE { version Version, modulus INTEGER, -- n publicExponent INTEGER, -- e privateExponent INTEGER, -- d prime1 INTEGER, -- …

Redis缓存(笔记一:缓存介绍和数据库启动)

目录 1、NoSQL数据库简介 2、Redis介绍 3、Redis(win系统、linux系统中操作) 3.1 win版本Redis启动 3.2 linux版本Redis启动 1、NoSQL数据库简介 技术的分类&#xff1a;&#xff08;发展史&#xff09; 1、解决功能性的问题&#xff1a;Java、Jsp、RDBMS、Tomcat、HTML、…

FreeRTOS任务调度机制(源码讲解)

任务的调度机制(核心是链表)&#xff01;&#xff01;&#xff01; 使用链表来管理任务 在我前面写的FreeRTOS任务(深入到源码进行分析)&#xff0c;我创建了三个任务&#xff0c;他们的优先级都是一样的&#xff0c;所以他们在FreeRTOS中是轮流执行的&#xff0c;实际上&…

【Python从入门到进阶】56、Mysql防止SQL注入及ORM库简化操作

接上篇《55、使用Python轻松操作Mysql数据库》 上一篇我们讲解了Mysql的基本链接和增删改查&#xff0c;本篇我们来介绍链接Mysql时参数化查询与防止SQL注入以及使用ORM&#xff08;对象关系映射&#xff09;库简化操作的内容。 一、参数化查询与防止SQL注入 在数据库操作中&…

Anaconda 出现HTTP000报错的解决方法

在使用Anaconda 安装python的时候遇到这个错误 chenchen-Standard-PC-i440FX-PIIX-1996:~$ conda create -n sdwebui python3.10.9Solving environment: failedCondaHTTPError: HTTP 000 CONNECTION FAILED for url <https://repo.anaconda.com/pkgs/r/noarch/repodata.jso…

如何跨渠道分析销售数据 - 6年软件销售经验小结

如何跨渠道分析销售数据 - 6年软件销售经验小结&#xff08;1&#xff09; 【前言】 在我过去6年销售工作生涯中&#xff0c;从第一年成为公司销冠后&#xff0c;我当时的确自满的一段时间&#xff0c;认为自己很了不起。但是第一年的销售业绩并没有拿到提成&#xff0c;最终…