C组暑假第一次训练题解

A.寄包柜

题意

两种操作

1.在第i个柜子第j个格子输入

2.输出第i个柜子第j个格子的数字

分析

因为i和j最大为1e5,使用二维数组会爆空间,使用map即可解决

代码

cpp 复制代码
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<map>
#include<vector>
#include<queue>
#include<set>
#include<iomanip>
#include<tuple>
#include<numeric>
//#include<stack>
//#include<deque>
//#include<bitset>
//#include<functional>

#define ll long long
#define inf 0x3f3f3f3f
#define lc p<<1
#define rc p<<1|1
#define endl '\n'
#define all(a) a.begin()+1,a.end()
#define pb push_back
using namespace std;

typedef pair<int,int>PII;

void solve()
{
	int n,q;
	cin>>n>>q;
	map<PII,int>mp;//这里的PII为pair<int,int>二元组
	while(q--)
	{
		int op;cin>>op;
		if(op==1)
		{
			int x,y,k;
			cin>>x>>y>>k;
			mp[{x,y}]=k;
		}
		else
		{
			int x,y;
			cin>>x>>y;
			cout<<mp[{x,y}]<<endl;
		}
	}
	
	
}
	
	
int main()
{
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	
	solve();
	
	return 0;
}

B.不重复数字

题意

给定n个数只保留第一次出现的数

分析

使用map或set都可以,但本题卡输入输出,需要关闭同步流

代码

cpp 复制代码
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<map>
#include<vector>
#include<queue>
#include<set>
#include<iomanip>
#include<tuple>
#include<numeric>
//#include<stack>
//#include<deque>
//#include<bitset>
//#include<functional>

#define ll long long
#define inf 0x3f3f3f3f
#define lc p<<1
#define rc p<<1|1
#define endl '\n'
#define all(a) a.begin()+1,a.end()
#define pb push_back
using namespace std;

typedef pair<int,int>PII;

void solve()
{
	int n;cin>>n;
	map<int,int>mp;
	while(n--)
	{
		int x;cin>>x;
		if(!mp[x]) cout<<x<<" ";
		mp[x]++;
	}
	
	cout<<endl;
	
	
}
	
	
int main()
{
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	int t;cin>>t;
	while(t--)
	solve();
	
	return 0;
}

C.文字处理软件

题意

4种操作,涉及到substr()函数和find()函数,具体用法自行搜索

代码

cpp 复制代码
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
string s,news;
int n,k;
int main()
{
    cin>>n>>news;
    while(n--)
    {
        cin>>k;
        if(k==1)
        {
            string ss;
            cin>>ss;
            news=news+ss;
            cout<<news<<endl;
        }
        
       else if(k==2)
        {
            int a,b;
            cin>>a>>b;
            news=news.substr(a,b);
            cout<<news<<endl;
        }
      else   if(k==3)
        {
            int a;
            string ss;
            cin>>a>>ss;
            news=news.insert(a,ss);
            cout<<news<<endl;
        }
       else if(k==4)
        {
            string ss;
            cin>>ss;
            if(news.find(ss)<news.size()) cout<<news.find(ss)<<endl;
            else cout<<-1<<endl;
        }
    }
    
    
    return 0;
}

D.ICPC Balloons

题意

给定只含大写字母的字符串,第一次出现的字母发两个气球,第二次出现后只发一个气球,求一共发多少气球

分析

map记录每个字母出现次数即可

代码

cpp 复制代码
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<map>
#include<vector>
#include<queue>
#include<set>
#include<iomanip>
#include<tuple>
#include<numeric>
//#include<stack>
//#include<deque>
//#include<bitset>
//#include<functional>

#define ll long long
#define inf 0x3f3f3f3f
#define lc p<<1
#define rc p<<1|1
#define endl '\n'
#define all(a) a.begin()+1,a.end()
#define pb push_back
using namespace std;

typedef pair<int,int>PII;

void solve()
{
	int n;cin>>n;
	string s;cin>>s;
	map<char,int>mp;
	int ans=0;
	for(auto c:s)
	{
		if(!mp[c]) ans+=2;
		else ans++;
		mp[c]++;
	}
	cout<<ans<<endl;
	
}
	
	
int main()
{
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	int t;cin>>t;
	while(t--)
	solve();
	
	return 0;
}

E.Remove Prefix

题意

给定n个整数,问删除前几个能使得剩下的数字只出现一次

分析

我们从后往前跑,将每个数字加入到set中直到出现重复数字,或者使用map维护每个数字出现次数

代码

cpp 复制代码
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<map>
#include<vector>
#include<queue>
#include<set>
#include<iomanip>
#include<tuple>
#include<numeric>
//#include<stack>
//#include<deque>
//#include<bitset>
//#include<functional>

#define ll long long
#define inf 0x3f3f3f3f
#define lc p<<1
#define rc p<<1|1
#define endl '\n'
#define all(a) a.begin()+1,a.end()
#define pb push_back
using namespace std;

typedef pair<int,int>PII;

void solve()
{
	int n;cin>>n;
	vector<int>f(n+1);
	for(int i=1;i<=n;i++) cin>>f[i];
	set<int>s;
	for(int i=n;i>=1;i--)
	{
		if(s.count(f[i])) {cout<<i<<endl;return;}
		else s.insert(f[i]);
	}
	
	cout<<0<<endl;//若前面没有return的话说明数组本身就无重复数字
}
	
	
int main()
{
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	int t;cin>>t;
	while(t--)
	solve();
	
	return 0;
}

F.Meximization

题意

给定一个数组a,对其重新排序使其所有前缀的mex之和最大,其中mex为不在集合中的最小非负整数,例如 MEX({1,2,3})=0、 MEX({0,1,2,4,5})=3

分析

根据mex的定义我们容易想到,如果我们将一个在原数列中已有的数放进去,那么 mex⁡ 值必定是不变的。所以,我们将所有数不重复地从小到大放入新数列中,再将原来没选进去的数按任意顺序放在最后,可以证明这样放的 mex⁡ 值最大。

代码

cpp 复制代码
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<map>
#include<vector>
#include<queue>
#include<set>
#include<iomanip>
#include<tuple>
#include<numeric>
//#include<stack>
//#include<deque>
//#include<bitset>
//#include<functional>

#define ll long long
#define inf 0x3f3f3f3f
#define lc p<<1
#define rc p<<1|1
#define endl '\n'
#define all(a) a.begin()+1,a.end()
#define pb push_back
using namespace std;

typedef pair<int,int>PII;

void solve()
{
	int n;cin>>n;
	vector<int>f(n+1);
	map<int,int>mp;
	int mx=-1e9;
	for(int i=1;i<=n;i++)
	{
		cin>>f[i];
		mp[f[i]]++;
		mx=max(mx,f[i]);//记录最大值
	}
	//第一次从小到大输出一遍
	for(int i=0;i<=mx;i++)
	{
		if(mp[i])
		{
			cout<<i<<" ";
			mp[i]--;
		}
	}
	//第二次将剩余的数输出
	for(int i=0;i<=mx;i++)
	{
		while(mp[i])
		{
			cout<<i<<" ";
			mp[i]--;
		}
	}
	cout<<endl;
}
	
	
int main()
{
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	int t;cin>>t;
	while(t--)
	solve();
	
	return 0;
}

G.Alice and Books

题意

翻译貌似有点小问题,但通过样例可以发现对于第一堆,Alice看的是页数最多的书,对于第二堆,Alice选择的是编号最大的书,也就是除了第n本书其中页数最多的书加上n即为答案

代码

cpp 复制代码
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<map>
#include<vector>
#include<queue>
#include<set>
#include<iomanip>
#include<tuple>
//#include<stack>
//#include<deque>
//#include<bitset>
//#include<functional>

#define ll long long
#define inf 0x3f3f3f3f
#define lc p<<1
#define rc p<<1|1
#define endl '\n'
#define all(a) a.begin()+1,a.end()
#define pb push_back
using namespace std;

typedef pair<int,int>PII;

void solve()
{
	int n;cin>>n;
	vector<int>f(n+1);
	for(int i=1;i<=n;i++) cin>>f[i];
	
	int k=0;
	for(int i=1;i<n;i++) k=max(f[i],k);
	cout<<k+f[n]<<endl;
	
	
}
	
	
int main()
{
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	int t;cin>>t;
	while(t--)
	solve();
	
	return 0;
}

H.Different String

题意

给定一个字符串,判断重新排列后其是否能形成一个新的字符串

分析

很明显只要字符串不全是一种字母就一定可以

代码

cpp 复制代码
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<map>
#include<vector>
#include<queue>
#include<set>
#include<iomanip>
//#include<stack>
//#include<deque>
//#include<bitset>
//#include<functional>

#define ll long long
#define inf 0x3f3f3f3f
#define lc p<<1
#define rc p<<1|1
#define endl '\n'
#define all(a) a.begin()+1,a.end()
#define pb push_back
using namespace std;

typedef pair<int,int>PII;

void solve()
{
	string s;cin>>s;
	map<char,int>mp;
	for(auto c:s) mp[c]++;
	if(mp.size()==1) cout<<"NO"<<endl;
	else
	{
		cout<<"YES"<<endl;
		cout<<s.substr(1,s.size()-1)<<s[0]<<endl;
	}
	
	
}
	
	
int main()
{
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	int t;cin>>t;
	while(t--)
	solve();
	
	return 0;
}

I.Matrix Stabilization

题意

给定一个n*m的矩阵,重复以下操作

若存在单元格(i,j)严格小于其所有相邻单元格(四周),则将该单元格值减1,若存在多个则选择i最小的,还存在多个选择j最小的

输出不能执行操作后的单元格

分析

观察样例可以发现,对于一个满足条件可以操作的单元格,其最终的值一定是其周围单元格值的最大值,基于以上性质,我们遍历矩阵,将所有可操作的单元格更改为最终值即可

代码

cpp 复制代码
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<map>
#include<vector>
#include<queue>
#include<set>
#include<iomanip>
#include<tuple>
//#include<stack>
//#include<deque>
//#include<bitset>
//#include<functional>

#define ll long long
#define inf 0x3f3f3f3f
#define lc p<<1
#define rc p<<1|1
#define endl '\n'
#define all(a) a.begin()+1,a.end()
#define pb push_back
using namespace std;

typedef pair<int,int>PII;
const int N=110;
int f[N][N];
void solve()
{
	int n,m;
	cin>>n>>m;
	for(int i=1;i<=110;i++)
	{
		for(int j=1;j<=110;j++) f[i][j]=0;
	}
	
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=m;j++) cin>>f[i][j];
	}
	
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=m;j++)
		{
			if(f[i][j]>f[i-1][j] && f[i][j]>f[i+1][j] && f[i][j]>f[i][j-1] && f[i][j]>f[i][j+1])
			{
				f[i][j]=max({f[i-1][j],f[i+1][j],f[i][j-1],f[i][j+1]});
			}
			cout<<f[i][j]<<" ";
		}
		cout<<endl;
	}
	
	
}
	
	
int main()
{
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	int t;cin>>t;
	while(t--)
	solve();
	
	return 0;
}

J.Shifts and Sorting

题意

给定一个01字符串,每次可执行以下操作

选择l和r,将s[l]和s[r]互换位置,代价为r-l+1,即所选子串长度

求将字符串变为非降序(即0在前,1在后)的最小代价

分析

贪心,如果当前位置是0,那么我们就将其与从左到右的第一个1互换(如果前面有1的话)

,这样可以保证所有1都在该0之前,我们用cnt记录1的个数,那么遇到0时交换产生的代价为cnt+1

代码

cpp 复制代码
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<map>
#include<vector>
#include<queue>
#include<set>
#include<iomanip>
//#include<stack>
//#include<deque>
//#include<bitset>
//#include<functional>

#define ll long long
#define inf 0x3f3f3f3f
#define lc p<<1
#define rc p<<1|1
#define endl '\n'
#define all(a) a.begin()+1,a.end()
using namespace std;

typedef pair<int,int>PII;

void solve()
{
	string s;cin>>s;
	ll cnt=0;
	ll ans=0;
	for(int i=0;i<s.size();i++)
	{
		if(s[i]=='1') cnt++;
		else
		{
			if(cnt!=0) ans+=cnt+1;
		}
	}
	cout<<ans<<endl;
	
}
	
	
int main()
{
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	int t;cin>>t;
	while(t--)
	solve();
	
	return 0;
}
相关推荐
scan72412 分钟前
LILAC采样算法
人工智能·算法·机器学习
菌菌的快乐生活33 分钟前
理解支持向量机
算法·机器学习·支持向量机
大山同学38 分钟前
第三章线性判别函数(二)
线性代数·算法·机器学习
axxy20001 小时前
leetcode之hot100---240搜索二维矩阵II(C++)
数据结构·算法
黑客Ash1 小时前
安全算法基础(一)
算法·安全
AI莫大猫2 小时前
(6)YOLOv4算法基本原理以及和YOLOv3 的差异
算法·yolo
taoyong0012 小时前
代码随想录算法训练营第十一天-239.滑动窗口最大值
c++·算法
Uu_05kkq2 小时前
【C语言1】C语言常见概念(总结复习篇)——库函数、ASCII码、转义字符
c语言·数据结构·算法
清梦20203 小时前
经典问题---跳跃游戏II(贪心算法)
算法·游戏·贪心算法
Dream_Snowar4 小时前
速通Python 第四节——函数
开发语言·python·算法