2021.5.7 2022蓝桥杯练习赛1

2021.5.7 2022蓝桥杯练习赛1

  1. 试题 算法训练 阶乘末尾
    2021.5.7 2022蓝桥杯练习赛1_第1张图片

本题问n的阶乘的后len为是多少,不足补前置零。
数据不大,n<=30可以直接暴力。len<=10,也就是说输出的数最大也才是一个十一位数,用long long就可以存在,所以没必要字符串模拟。
但是如果先算n!的话long long是存不下的,所以在暴力的时候每次要去%pow(10,len)

#include
using namespace std;
int main()
{
     
	long long int n,len,sum=1,i,k;
	cin>>n>>len;
	long long int t=pow(10,len);
	for(i=1;i<=n;i++)
	{
     
		sum*=i;
		sum=sum%t;
	}
	k=t/10;
	for(i=0;i<len;i++)
	{
     
		cout<<sum/k;
		sum%=k;
		k/=10;
	}
}
  1. 试题 算法提高 断案
    2021.5.7 2022蓝桥杯练习赛1_第2张图片
    自己想,小偷会是乙,输出B
#include
using namespace std;
int main()
{
     
	cout<<"B";
}
  1. 试题 算法训练 集合运算
    2021.5.7 2022蓝桥杯练习赛1_第3张图片
    要求:
    第一行输出集合A与集合B的交集 (这里我用set< int >c存)
    第二行输出集合A与集合B的并集 (这里我用set< int >s1存)
    第三行输出B在A中的余集中的所有元素,就是要输出那些在集合A有的且在集合B中没有的元素 (这里我就没有额外开数组了,而是遍历数组a,如果a[i]不在set< int >c里面,那么就输入a[i])
#include
using namespace std;
int n,m;
int a[1005],b[1005];
set<int>c;  //交集 
set<int>s1;	//并集 set有去重和自动排序的好处 
int main(){
     
    cin>>n;
    for(int i=1;i<=n;i++) {
     
        cin>>a[i];
        s1.insert(a[i]);     //将a[i]加入s1中 
    }
    cin>>m;
    for(int i=1;i<=m;i++) {
     
        cin>>b[i];
        if(s1.count(b[i])) c.insert(b[i]);  //如果s1中有元素b[i],就说明数组a中也有一个元素值等于b[i],即数组A和B的交集 
        s1.insert(b[i]);                    //将b[i]加入s1中 
    }
    set<int>::iterator it;   //练习系统用不了auto ,所以自己写 
    for(it=c.begin();it!=c.end();it++)cout<<*it<<" ";   //输出交集 
    puts("");
    for(it=s1.begin();it!=s1.end();it++) cout<<*it<<" "; //输出并集 
    puts("");
    sort(a+1,a+n+1);    //由于数组a还没有排序,所以先排个序 
    for(int i=1;i<=n;i++){
     
        if(!c.count(a[i])) cout<<a[i]<<" ";  //如果不是数组A和B的交集,那么就说明当前元素a[i]只存在与数组A中而不在数组B中 
    } 
    puts("");

}

  1. 试题 算法训练 入学考试
    2021.5.7 2022蓝桥杯练习赛1_第4张图片
    这个题一看就是01背包问题的模板题,所以要动态规划
    (最后面会附上背包类问题的学习链接)
#include
using namespace std;
int main()
{
     
	int T,m;
	int t[105],v[105],f[15000];
	cin>>T>>m;
	for(int i=1;i<=m;i++)
	{
     
		cin>>t[i]>>v[i];
	}
	for(int i=1;i<=m;i++)
	{
     
		for(int j=T;j>=t[i];j--)
		{
     
			f[j]=max(f[j-t[i]]+v[i],f[j]);
		}
	}
	cout<<f[T];
}
  1. 试题 算法训练 纪念品分组
    2021.5.7 2022蓝桥杯练习赛1_第5张图片
    2021.5.7 2022蓝桥杯练习赛1_第6张图片
    数据n<=30000,所以O(n^2)的做法肯定是不可以的。
    在看题目说了每组最多只能包含两件纪念品,那么贪心想法就来了,本题我认为就是贪心思想。
    我先将所有纪念品价值从小到大排序,定义i指向数组的最前面,然后定义j从后往前找,如果当前a[i]+a[j]<=w,是不是就说明了这两个纪念品可以分为一组,随后i++;否则的话,我就将a[j]单独分为一组。
    最终不满足while(j>=i)时,即已经将所有纪念品分好组了。
#include
using namespace std;
int w,n;
int a[30005];
int sum;
int main(){
     
    scanf("%d%d",&w,&n);
    for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    sort(a+1,a+n+1);
    int i=1,j=n;
    while(j>=i){
     
        if(a[j]+a[i]<=w) i++;
        sum++;
        j--;
    }
    cout<<sum<<endl;
    return 0;
} 
  1. 试题 算法训练 字符串编辑
    2021.5.7 2022蓝桥杯练习赛1_第7张图片
    本题简单说:就是题目要干什么就完成什么,按照题目说的来写就可以了。
    需要注意的地方:
    1、‘D’: 是删除那个字符第一次出现的地方,从前往后遍历
    2、’I’: 是插入最后一个字符前面,从后往前遍历
    3、‘R: 是替换所有该字符,从前往后或从后往前都可以
    4、可能因为有空格的读入,难在了读入字符串上面。可以了解一下getline(cin,s) 就好了
#include
using namespace std;
string s;
char q,x,y;
int main(){
     
    getline(cin,s);
    cin>>q;
    if(q=='D'){
     
        cin>>x;
        int i=0;
        for(i=0;i<s.length();i++){
     
            if(s[i]==x){
     
                break;
            }
            else{
     
                cout<<s[i];
            }
        }
        for(int j=i+1;j<s.length();j++) cout<<s[j];
    }
    else if(q=='I'){
     
        cin>>x>>y;
        int idx;
        for(int i=s.length()-1;i>=0;i--){
     
            if(s[i]==x){
     
                idx=i;
                break;
            }
        }
        for(int i=0;i<s.length();i++){
     
            if(idx!=i) cout<<s[i];
            else{
     
                cout<<y<<s[i];
            }
        }
    }
    else{
     
        cin>>x>>y;
        for(int i=0;i<s.length();i++){
     
            if(s[i]==x) cout<<y;
            else cout<<s[i];
        }
    }
}

附:背包九讲

你可能感兴趣的:(蓝桥杯,c++)