2022年12月STEMAC++中级组编程题

第一题:

编程实现:求位数
题目描述:
给定一个正整数N(1<N<10^8),输出N为几位数。
输入描述
输入一个正整数N(1<N<10^8)
输出描述
输出一个整数,表示N为几位数。

解析:这题可以直接通过循环除法求商得出有几位数。

#include<iostream>
using namespace std;
int main(){
    int N;
    cin>>N;
    int ans = 0;
    while(N>0){
        N /= 10;
        ans++; 
    }
    cout<<ans;
    return 0;
}


第二题:

编程实现:字符反转
题目描述:
给定一个只包含大写字母“M”和“W”的字符串(字符串长度小于100),
然后对字符串中位置为偶数的字符进行反转(M反转为W,W反转为M;字符串中左边第1个字符位置为1)。
例如:原字符串为“WMMW”,反转后为“WWMM”
输入描述
输入一个只包含大写字符“M”和“W”的字符串(字符串长度小于100)
输出描述
输出一个字符串,表示对原字符串中位置为偶数的字符反转后的字符串

解析:本题考查字符串的操作,也是考查数组的操作。注意:题目中的序号和原来的字符串下标不同,字符序号=字符下标+1。通过遍历每个字符元素,如果满足序号是偶数就进行翻转。

#include<iostream>
#include<cstring>
using namespace std;
int main(){
    string str;
    cin>>str;
    for(int i=0;i<str.size();i++){
        if((i+1)%2==0){
            if(str[i]=='W'){
                str[i]='M';
            }
            else if(str[i]=='M'){
                str[i]='W';
            }
        }
    }
    cout<<str;
    return 0;
}

第三题:

编程实现:排名
题目描述:
某比赛有N(2≤N≤50)名选手参加,   N
给定每名参赛选手的编号(1到N)和比赛得分(0≤得分≤100),  编号唯一 1-N
请按照分数从高到低的顺序排序,如果分数相同就按照编号排序,
分数从高到低     如果分数相同就按照编号排序
编号小的排前边。

解析:因为每一个选手有两个参数:编号和成绩,编号和成绩是对应的。可以使用一维数组来实现,也可以使用二维数组来实现。排序的方法可以使用冒泡/插入等,反正你会用哪个就用哪个。

#include<iostream>
using namespace std;
int main(){
    int N;
    cin>>N;//输入的要求
    int a[N+1],b[N+1]; //设置N+1个元素,仅仅只是为了简单处理编号与下标对应问题 
    //输入编号和成绩 
    for(int i=1;i<=N;i++){
        cin>>a[i]>>b[i];//满足输入描述中的第二行开始的要求
        //scanf("%d %d",a[i],b[i]);
    } 
    //排序 
    //冒泡排序。为了实现高到低排序
    //每轮将最小的成绩移至最后::
    for(int i=1;i<N;i++){
        for(int j=1;j<=N-i;j++){//因为每轮比较都能将最小元素往后移 
            int temp; 
            if(b[j]<b[j+1]){
                //成绩交换排序顺序
                temp = b[j];
                b[j] = b[j+1];
                b[j+1] = temp;
                //编号交换排序顺序
                temp = a[j];
                a[j] = a[j+1];
                a[j+1] = temp;
            }
            else if(b[j]==b[j+1]){
                if(a[j]>a[j+1]){//当成绩相同时,编号大往后排
                    //编号交换排序顺序
                    temp = a[j];
                    a[j] = a[j+1];
                    a[j+1] = temp;
                }
            }
        }
        
    } 

//以上就是排序区域

 //输出区域:注意输出格式。按照排序规则输出N行,每行两个正整数,

 //分别表示编号和得分,正整数之间以一个空格隔开 

 for(int k=1;k<=N;k++){
        cout<<a[k]<<" "<<b[k]<<endl;
    } 
     
    return 0; 
} 

第四题:

充电站
题目描述:
一条笔直的公路沿途有N(2≤N≤100)个充电站,包含起点和终点各一个。
小明驾驶电动汽车要从公路的起点到达终点。
已知电动汽车充满电后可行驶的里程数D(10≤D≤10000),
及N个充电站每相邻的两个充电站之间的距离,
并且小明在起点第一次给电动汽车充满电。
请帮助小明计算出最少充电几次才能从起点到达终点
(需包含起点的第一次充电)。

注意:
1)到达终点后不需要再充电;
2)每次充电都要充满。

例如:D = 10,N = 7,N-1
7个充电站之间的距离依次为1,3,6,8,1,4,
最少需要充电3次。

第一次充电在起点(第1个充电站);  充电次数一开始就为1
第二次充电在第4个充电站(此时行驶里程为10,刚好电量耗尽);
第三次充电在第6个充电站(此时在第二次充满电后行驶里程为9,
剩余电量只能行驶1,距离下一充电站的距离为4,所以必须在此充电站充电)。

解析:需要注意充电次数从一开始就为1。可以使用一个临时变量作为汽车的当前剩余电量。

#include<iostream>
using namespace std;
int main(){
    int D ,N;
    cin>>D>>N;
    int c[N-1];
    //第二行输入N-1个正整数(1≤正整数≤100000),
    //依次表示相邻两个充电站之间的距离,正整数之间以一个空格隔开
    for(int i=0;i<N-1;i++){//输入N-1个正整数,表示各个充电站间的距离 
        cin>>c[i]; 
    } 
    //注意:汽车在起点时有一个充电站,并且充满了电
    //用一个变量ans来表示充电次数,初始值为1
    int ans = 1;
    int temp = D ;//D表示汽车的每次可充电上限,temp表示汽车的可用电量 
    for(int i=0;i<N-2;i++) {//如果下一站距离超过了满电行驶上限 
        if(c[i+1]>D){
            ans = -1;//直接给-1 
            break;
        } 
        temp -= c[i];//每次到达一个充电站消耗后剩余的电量
        if(temp<c[i+1]) {
            temp = D;//充满电
            ans++;//充电次数+1 
        }
    }
    cout<<ans;
    return 0; 
} 

第五题:

猴子拿桃

题目描述:

有N筐桃子从左到右排成一排,已知每筐桃子的数量。现猴子要按照以下规则拿取桃子:

1)猴子每次拿一筐桃子,一共要拿K次桃子;

2)猴子只能按照从左到右的顺序拿取桃子,不能回头,且每次拿取桃子的数量不能少于(大于等于)上一次。

当给定桃子筐数N(1≤N≤12)及每筐桃子的数量,和要拿取桃子的次数K(1≤K≤N),请编写程序,如果有符合规则的拿取方式,输出猴子最多可以拿到的桃子数量,否则输出0。

例如:

N = 4,4筐桃子的数量从左到右依次为16,12,16,17;

K=3,猴子一共要拿3次桃子,符合规则的拿取方式有:[16,16,17],[12,16,17];

其中可拿取到最多桃子的方式是:[16,16,17],合计为49。则猴子最多可以拿到49个桃子。

输入描述
第一行输入两个正整数N和K(1≤N≤12,1≤K≤N),分别表示桃子的筐数和一共要拿取桃子的次数,正整数之间以一个空格隔开

第二行输入N个正整数(10≤正整数≤200),从左到右依次表示每筐桃子的数量,正整数之间以一个空格隔开

输出描述
输出一个整数,如果有符合规则的拿取方式,输出猴子最多可以拿到的桃子数量,否则输出0

解析:使用一个临时变量当做滑动窗口,记录每次进行组合时下一个不小于当前数的位置。

#include <iostream>
using namespace std;
int main(){
    int N,K;
    cin>>N>>K;
    //输入N个数
    int a[N],b[K];
    for(int i=0;i<N;i++){
        cin>>a[i];
    } 
    //从第一个元素开始进行组合K个数,最多执行到N-K
    /*2*/int count  = 0; 
    int sum = 0;//计算组合的总和
    int max = 0;//对总和求最大值 
    for(int i=0;i<N-K;i++){
        int temp = i;//在每回组合中,temp作为下标滑动窗口存在
        b[0] = a[temp];//当前i的位置作为组合的第一个元素
        /*2*/count = 1;
        for(int j=1;j<K;j++){ //对b[K]中的剩余位置进行填充 
            //填充条件:下一个元素不小于(>=)现在元素
            for(int k=temp;k<N;k++){
                if(a[k+1]>=a[k]){
                    b[j] = a[k+1];
                    /*2*/count++;
                    temp = k+1;//更新窗口的所在下标 
                    break; 
                } 
            }    
        } 
        if(count<K){
            cout<<"0";
            return 0;
        } 
        else{
            sum = 0;
            for(int i=0;i<K;i++){
                sum+=b[i];
            } 
            if(max<sum){
                max = sum;
            }
        }
    } 
    cout<<max;
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值