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;
}
相关推荐
云卓SKYDROID13 分钟前
除草机器人算法以及技术详解!
算法·机器人·科普·高科技·云卓科技·算法技术
半盏茶香37 分钟前
【C语言】分支和循环详解(下)猜数字游戏
c语言·开发语言·c++·算法·游戏
徐子童41 分钟前
双指针算法习题解答
算法
想要打 Acm 的小周同学呀1 小时前
LRU缓存算法
java·算法·缓存
劲夫学编程2 小时前
leetcode:杨辉三角
算法·leetcode·职场和发展
毕竟秋山澪2 小时前
孤岛的总面积(Dfs C#
算法·深度优先
浮生如梦_4 小时前
Halcon基于laws纹理特征的SVM分类
图像处理·人工智能·算法·支持向量机·计算机视觉·分类·视觉检测
励志成为嵌入式工程师6 小时前
c语言简单编程练习9
c语言·开发语言·算法·vim
捕鲸叉6 小时前
创建线程时传递参数给线程
开发语言·c++·算法
A charmer6 小时前
【C++】vector 类深度解析:探索动态数组的奥秘
开发语言·c++·算法