IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> Codeforces Round #486 (Div. 3)【完结】 -> 正文阅读

[数据结构与算法]Codeforces Round #486 (Div. 3)【完结】

2022.3.2
题单地址:https://codeforces.com/contest/988

在这里插入图片描述

A. Diverse Team【模拟】

在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int a[N],st[N],n,k;
vector<int>ve;
int main(void)
{
	cin>>n>>k;
	for(int i=0;i<n;i++) cin>>a[i];
	for(int i=0;i<n;i++)
	{
		if(!st[a[i]]) ve.push_back(i+1);
		if(ve.size()==k) break;
		st[a[i]]++;
	}
	if(ve.size()==k) 
	{
		puts("YES");
		for(int i=0;i<ve.size();i++) cout<<ve[i]<<" ";
	}else puts("NO");
	return 0;
}

B. Substrings Sort【暴力枚举】

在这里插入图片描述
先按长度从小到大排序,然后在判断当前字符串的的子串有没有上一个字符串

#include<bits/stdc++.h> 
using namespace std;
const int N=1e5+10;
string s[N];
int n;
bool cmp(string a,string b){return a.size()<b.size();}
int main(void)
{
	cin>>n;
	for(int i=0;i<n;i++) cin>>s[i];
	sort(s,s+n,cmp);
	for(int i=1;i<n;i++)
	{
		int m=s[i].size();
		bool flag=0;
		for(int len=1;len<=m;len++)
		{
			for(int j=0;j+len<=m;j++)
			{
				string temp=s[i].substr(j,len);
				if(temp==s[i-1]) flag=1;
			}
		}
		if(!flag) 
		{
			puts("NO");
			return 0;
		}
	}
	puts("YES");
	for(int i=0;i<n;i++) cout<<s[i]<<endl;
	return 0;
}

C. Equal Sums【哈希表】

在这里插入图片描述
注意开long long
求每一行的和。
然后枚举每一行,删除一个数后的值,存一下。
如果已经存过了,且不是同一行,那么说明找到了。

#include<bits/stdc++.h>
using namespace std;
typedef long long int LL;
typedef pair<int,int> PII;
const int N=1e5*4+10;
vector<LL>ve[N];
LL k,n,x,s[N];
unordered_map<LL,PII>mp;
int main(void)
{
	scanf("%d",&k);
	for(int i=1;i<=k;i++)
	{
		scanf("%d",&n);
		for(int j=0;j<n;j++) scanf("%d",&x),ve[i].push_back(x),s[i]+=x;
	}
	for(int i=1;i<=k;i++)
	{
		for(int j=0;j<ve[i].size();j++)
		{
			x=s[i]-ve[i][j];
			if(mp.count(x)&&mp[x].first!=i)//存在,且不是同一行
			{
				puts("YES");
				auto temp=mp[x];
				cout<<temp.first<<" "<<temp.second<<endl;
				cout<<i<<" "<<j+1;
				return 0;
			}
			mp[x]={i,j+1};
		}
	}
	puts("NO");
	return 0;
}

D. Points and Powers of Two【数学结论题 + 暴力枚举】

在这里插入图片描述
在这里插入图片描述
由上可知,答案的最大长度为3,且相邻两项的差是固定的。
故可以直接枚举首相和差。找到最长的答案即可。
注意开long long,注意剪枝枚举前三项即可。找到一个长度未3的结果就可以直接不用找了。
特别需要注意的是用map,用哈希表会超时,这是因为在枚举的时候查找如果没有则会创建到哈希表里,而建哈希表的结点是十分耗时间的。

#include<bits/stdc++.h>
using namespace std;
typedef long long int LL;
const int N=1e5*4+10;
map<LL,int>mp; 
LL a[N],b[N],n;
vector<LL>ans;
int main(void)
{
	cin>>n;
	for(int i=0;i<n;i++) scanf("%lld",&a[i]),mp[a[i]]++;
	for(int i=0,k=1;i<=30;i++,k*=2) b[i]=k;
	sort(a,a+n);
	for(int i=0;i<n;i++)
	{
		vector<LL>ve; ve.push_back(a[i]);
		if(ans.size()==3) break;
		for(int k=0;k<=30;k++)
		{
			vector<LL>temp=ve;
			LL tempx=temp[0];
			while(mp[tempx+b[k]]) 
			{
				tempx=tempx+b[k];
				temp.push_back(tempx);
				if(temp.size()==3) break;
			}
			if(temp.size()>ans.size()) ans=temp;
			if(ans.size()==3) break; 
		}
	}
	cout<<ans.size()<<endl;
	for(int i=0;i<ans.size();i++) cout<<ans[i]<<" ";
	return 0;
}

E. Divisibility by 25【贪心】

在这里插入图片描述
能背25整除的结尾无非四种情况

  • 以25结尾
  • 以50结尾
  • 以75结尾
  • 以00结尾

大致思路枚举四种情况找到最小的步数,从后往前找找到第一个数将其移到指定位置。再找第二个数将其移到指定位置。
需要注意的是,这时候可能有前导0,这时候再从前到后的找到一个非零的数将其移到开头。

/*25
50
75
00
*/
#include<bits/stdc++.h>
using namespace std;
string s;
int ans=1e9;
void solve(char a,char b)
{
	int index=0,flag=0,cnt=0;
	for(int i=s.size()-1;i>=0;i--) 
	{
		if(s[i]==b) 
		{
		    index=i,flag=1;
			break;
		}
	}
	if(!flag) return;
	while(index+1<s.size()) swap(s[index],s[index+1]),index++,cnt++;

	index=0,flag=0;
	for(int i=s.size()-2;i>=0;i--) 
	{
		if(s[i]==a) 
		{
			index=i,flag=1;
			break;
		}
	}
	if(!flag) return;
	while(index+1<s.size()-1) swap(s[index],s[index+1]),index++,cnt++;
	
	index=0,flag=0;
	for(int i=0;i<s.size()-2;i++)//解决前导0
	{
	    if(s[i]!='0')
	    {
	        index=i,flag=1;
	        break;
	    }
	}
	while(index-1>=0) swap(s[index],s[index-1]),index--,cnt++;
	if(s[0]=='0') return;
	ans=min(ans,cnt);
}
int main(void)
{
	cin>>s;
	string temp=s;
	solve('2','5'); s=temp;
	solve('5','0'); s=temp;
	solve('7','5'); s=temp;
	solve('0','0'); s=temp;
	if(ans==1e9) puts("-1");
	else cout<<ans;
	return 0;
}

F. Rain and Umbrellas【DP】

在这里插入图片描述
状态表示: dp[i]表示从[0-i]的疲劳度
对于这种区间问题我们一般这样表示rain[i] 表示 [i,i+1]这一段区间 这样的话便于处理。

#include<bits/stdc++.h> 
using namespace std;
const int N=1e5+10;
typedef long long int LL;
int a,n,m;
LL rain[N],w[N],dp[N];
int main(void)
{
	cin>>a>>n>>m;
	while(n--)
	{
		int l,r; cin>>l>>r;
		for(int i=l;i<=r-1;i++) rain[i]=1;
	}
	
	while(m--)
	{
		LL x,c; cin>>x>>c;
		if(!w[x]) w[x]=c;
		else w[x]=min(w[x],c);
	}
	
	for(int i=0;i<=a;i++) dp[i]=1e18;
	dp[0]=0;
	for(int i=1;i<=a;i++)
	{
		if(!rain[i-1]) dp[i]=dp[i-1];//说明这一段区间是无雨的
		else//有雨
		{
			for(int j=0;j<i;j++)
				if(w[j]) dp[i]=min(dp[i],dp[j]+(i-j)*w[j]);
		}
	}
	if(dp[a]==1e18) puts("-1");
	else cout<<dp[a];
	return 0;
}
  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-03-03 16:39:43  更:2022-03-03 16:42:28 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 15:42:28-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码