【每日一题】—— D. Prefix Permutation Sums (Codeforces Round 888 (Div. 3))

🌏博客主页:PH_modest的博客主页

🚩当前专栏:每日一题

💌其他专栏:

🔴 每日反刍

🟡 C++跬步积累

🟢 C语言跬步积累

🌈座右铭:广积粮,缓称王!

一.题目描述


题目大意:你的朋友有一个长度为n的数组,该数组中的数字是由1~n组成,不会有重复的数字,他计算了前缀和并将其传递给你,但再传递过程中丢失了一个数(前缀和中的一个数),你需要根据缺失的前缀和数组判断是否有与其匹配的置换。

例如,原始置换为[ 1、5、2、4、3]。其前缀和数组 [ 1、6、8、12、15]。丢失一个元素,可以得到数组[ 6、8、12、15]或[ 1、6、8、15]。
题目链接:D. Prefix Permutation Sums (Codeforces Round 888 (Div. 3))

二.思路分析

  1. 首先这里需要知道一个前缀和的性质,第n个前缀和减去第n-1个前缀和得到的是第n个数字
  2. 还有一个重要的点就是,如果缺失的数字不是最后一个,那么会导致缺失的前缀和左右的数字之差为原数组中两个数字之和;如果是最后一个那么就只会少一个数
  3. 那么我们可以先根据已知的前缀和数组求出当前的数字(这里特别提醒一下,第一个前缀和就表示第一个数),将他们存放到map容器中,如果不知道map容器的话可以私信问我,如果问的人比较多的话会单独写一篇关于map容器的博客,然后从1开始遍历到n判断mp中是否有对应的数字,如果没有就将这些数字相加,再找。

    大概思路应该都解释清楚了,剩下还有一些小细节就交给你们自己处理一下,遇到什么问题可以评论区提问,或者私信博主,如果不太理解可以多举几个例子。

三.代码展示

cpp 复制代码
#include<iostream>
#include<map>
#define int long long
using namespace std;

int s[200020];
map<int,int>mp;//存放前缀和之间的差值
void solve()
{
	int n;
	mp.clear();//初始化
	cin>>n;
	for(int i=0;i<n-1;i++)
	{
		cin>>s[i];
	}
	mp[s[0]]++;//将第一个前缀和数字放入
	for(int i=1;i<n-1;i++)
	{
		mp[s[i]-s[i-1]]++;//放入两个相邻前缀和的差值
	}
	int sums=0;//记录原数组中少的数字之和是多少
	int flag=0;//原数组少了几个数字
	for(int i=1;i<=n;i++)
	{
		if(mp[i]==0)//少了的数字
		{
			sums+=i;
			flag++;
		}
		if(mp[i]>0)//如果这个数字没有少,就需要把之前的标记撤销掉,如果不撤销会出问题,想想为什么
		{
			mp[i]--;
		}
	}
	if(flag==1)//如果flag为1,说明丢失的是最后一个数,无论怎么样都符合条件
	{
		cout<<"YES"<<"\n";
		return;
	}
	if(flag>2)//如果大约2直接输出no
	{
		cout<<"NO"<<"\n";
		return;
	}
	if(flag==2)//等于2说明丢失的是前面的数字
	{
		if(mp[sums]==0)//丢失的数字之和没有被标记
		{
			cout<<"NO"<<"\n";
			return;
		}
		else
		{
			cout<<"YES"<<"\n";
			return;
		}
	}

}

signed main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	
	int t;
	cin>>t;
	while(t--)
	{
		solve();
	}
	
	return 0;
}

最后:

每日一题系列旨在养成刷题的习惯,所以对代码的解释并不会特别详细,但足够引导大家写出来,选的题目都不会特别难,但也不是特别简单,比较考验大家的基础和应用能力,我希望能够将这个系列一直写下去,也希望大家能够和我一起坚持每天写代码。
之后每个星期都会不定期更新codeforces和atcoder上的题目,想要学习算法的友友们千万别错过了,有什么疑问欢迎大家在评论区留言!
在这里送大家一句话:广积粮,缓称王!

相关推荐
apocelipes2 分钟前
使用libdivide加速整数除法运算
c语言·c++·性能优化·linux编程
liang_20264 分钟前
【HT周赛】T3.二维平面 题解(分块:矩形chkmax,求矩形和)
数据结构·笔记·学习·算法·平面·总结
緈福的街口5 分钟前
【leetcode】2900. 最长相邻不相等子序列 I
算法·leetcode·职场和发展
虾球xz6 分钟前
游戏引擎学习第290天:完成分离渲染
c++·人工智能·学习·游戏引擎
易只轻松熊6 分钟前
C++(20): 文件输入输出库 —— <fstream>
开发语言·c++·算法
虾球xz8 分钟前
游戏引擎学习第285天:“Traversables 的事务性占用”
c++·学习·游戏引擎
芯眼10 分钟前
ALIENTEK精英STM32F103开发板 实验0测试程序详解
开发语言·c++·stm32·单片机·嵌入式硬件·社交电子
【正弦】27 分钟前
深入理解构造函数,析构函数
c++
远瞻。27 分钟前
【论文阅读】人脸修复(face restoration ) 不同先验代表算法整理
论文阅读·算法
进击的小白菜32 分钟前
LeetCode 153. 寻找旋转排序数组中的最小值:二分查找法详解及高频疑问解析
数据结构·算法·leetcode