蓝桥杯(C、C++)B组 练习第①篇

目录

 1.数组插入元素并排序

 2.计算及格率和优秀率

 3.区间K大数查询

 4.日期读取混乱问题

 5.分巧克力 


 1.数组插入元素并排序

【问题描述】

有一个整型数组a[1000],已经按从小到大顺序排好。现输入一个数x,请编写一个函数,将该数插入到数组中,并使数组仍然保持从小到大有序。

要求:不得使用排序函数,尽量提高效率。

【样例输入输出】

输入:

5

1 3 4 7 10

输出:

1 3 4 5 7 10

#include <stdio.h>

int main() {
    int a[1001], n, i, j, x;
	scanf("%d", &n);			//读取数组的长度n 
    scanf("%d", &x);			//读取需要插入的元素x 
    
    for (i = 0; i < n; i++) {															//n 
        scanf("%d", &a[i]);				//输入已经排好顺序的数组元素 
    }
    				
    // 从后往前遍历数组,将大于等于x的元素后移一位,直到找到第一个小于等于x的元素
    for (i = n - 1; i >= 0 && a[i] > x; i--) {
        a[i + 1] = a[i];
    }
    // 将x插入到该位置
    a[i + 1] = x;
    for (i = 0; i < n + 1; i++) {													//n+1
        printf("%d ", a[i]);				//打印数组,此时元素个数多了一个 
    }
    return 0;
}

 2.计算及格率和优秀率

 【问题描述】
小蓝给学生们组织了一场考试,卷面总分为100分,每个学生的得分都是一个0到100的整数。
如果得分至少是60分,则称为及格。如果得分至少为85分,则称为优秀。
请计算及格率和优秀率,用百分数表示,百分号前的部分四舍五入保留整数。
【输入格式】 
输入的第一行包含一个整数n,表示考试人数。接下来n行,每行包含一个0至100的整数,
表示一个学生的得分。
【输出格式】
输出两行,每行一个百分数,分别表示及格率和优秀率。
百分号前的部分四舍五入保留整数。


//C 解法
#include <stdio.h>
#include <math.h>
int main()
{
    int n;
    scanf("%d", &n);

    int total_score = 0; // 总分
    int pass_count = 0; // 及格人数
    int excellent_count = 0; // 优秀人数

    for (int i = 0; i < n; i++)
    {
        int score;
        scanf("%d", &score);
        total_score += score;

        if (score >= 60)
        {
            pass_count++;

            if (score >= 85)
            {
                excellent_count++;
            }
        }
    }

    double pass_rate = (double)pass_count / n * 100; // 计算及格率
    double excellent_rate = (double)excellent_count / n * 100; // 计算优秀率

    // 输出结果
//    对于四舍五入保留整数位的输出,我们将double类型的结果强制类型转换为int类型,
//    并使用printf函数来输出带有百分号的整数,它的格式是:%d%%。
    printf("%d%%\n", (int)(round(pass_rate))); // 四舍五入保留整数位输出
    printf("%d%%\n", (int)(round(excellent_rate))); // 四舍五入保留整数位输出
	//C语言中没有double类型的round函数,我们需要使用math.h头文件中的函数来进行四舍五入。
    return 0;
}




//C++ 解法
#include <iostream>
#include <iomanip> // 用于输出保留小数点后若干位的数据
#include <cmath> // 用于四舍五入函数round

using namespace std;

int main()
{
    int n;
    cin >> n;

    int total_score = 0; // 总分
    int pass_count = 0; // 及格人数
    int excellent_count = 0; // 优秀人数

    for (int i = 0; i < n; i++)
    {
        int score;
        cin >> score;	//输入没行的分数 
        total_score += score;	//每行分数相加 

        if (score >= 60)
        {
            pass_count++;		//及格人数 

            if (score >= 85)
            {
                excellent_count++;		//优秀人数 
            }
        }
    }
	//除法运算可能导致小数点后数据丢失,所以我们使用static_cast来将int类型转换为double类型
    double pass_rate = static_cast<double>(pass_count) / n * 100; // 计算及格率
    double excellent_rate = static_cast<double>(excellent_count) / n * 100; // 计算优秀率

    // 输出结果
    cout << round(pass_rate) << "%" << endl;
    cout << round(excellent_rate) << "%" << endl;
	//可以使用cmath头文件中的round函数对数据进行四舍五入处理。
    return 0;
}

 3.区间K大数查询

【问题描述】

/*给定一个序列,每次询问序列中第l个数到第r个数中第K大的数是哪个。

输入格式
输入描述:
第一行包含一个数n,表示序列长度。

第二行包含n个正整数,表示给定的序列。

第三个包含一个正整数m,表示询问个数。

接下来m行,每行三个数l,r,K,表示询问序列从左往右第l个数到第r个数中,从大往小第K大的数是哪个。序列元素从1开始标号。

输入样例:
5
1 2 3 4 5
2
1 5 2
2 3 2
输出格式

输出描述:
总共输出m行,每行一个数,表示询问的答案。
输出样例:
4
2

保证k<=(r-l+1),序列中的数<=106。
*/
 

#include <stdio.h>

void bubble_sort(int a[], int n)  //冒泡排序 顺序为从大到小排列
{
    int i,j,temp;

    for(j=0;j<n-1;j++)
    {
        for(i=0;i<n-1-j;i++)
        {
            if(a[i]<a[i+1])
            {
                temp=a[i];
                a[i]=a[i+1];
                a[i+1]=temp;
            }
        }
    }
}

int main() {
    int n,m,l,r,k;
    int i,j;   //用于循环

    scanf("%d",&n);   //输入n值,表示序列长度

    int a[n],b[n];   //a[n]为原始序列,b[n]为备份序列,用于排序操作

    for(i=0;i<n;i++)
    {
        scanf("%d",&a[i]);
    }   //输入一串序列

    scanf("%d",&m);    //输入询问个数m;

    for(i=0;i<m;i++)
    {
        int num=0;

        scanf("%d%d%d",&l,&r,&k);   //输入l,r、k的值 ,l为询问起始位置,r为询问结束位置,k为询问区间内第k大的数

        for(j=l-1;j<r;j++)
        {
            b[num++]=a[j];
        }   //将需要询问的区间取出备份到b[]序列

        bubble_sort(b,num);

        printf("%d\n",b[k-1]);  //直接输出第k大的数,注意:第一大的数为b[0],所以用 k-1;
    }
    return 0;
}

  4.日期读取混乱问题

【问题描述】
小明正在整理一批历史文献。这些历史文献中出现了很多日期。小明知道这些日期都在1960年1月1日至2059年12月31日。
令小明头疼的是,这些日期采用的格式非常不统一,有采用年/月/日的,有采用月/日/年的,还有采用日/月/年的。
更加麻烦的是,年份也都省略了前两位,使得文献上的一个日期,存在很多可能的日期与其对应。比如02/03/04,
可能是2002年03月04日、2004年02月03日或2004年03月02日。\n给出一个文献上的日期,你能帮助小明判断有哪些可能的日期对其对应吗?
【输入描述】
—个日期,格式是\"AA/BB/CC\"(0≤A,B,C≤9)。
【输出描述】
输出若干个不相同的日期,每个日期一行,格式是\"yyyy—MM —dd\"。多个日期按从早到晚排列。

//学会自己理解代码逻辑喔

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;

int days[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
bool check(int year,int month,int day){
	if(month==0||month>12)return false;
	if(day==0)return false;
	if(month!=2){
		if(day>days[month])return false;
	}else{
		int leap=(year%4==0&&year%100!=0)||(year%400==0);
		if(day>28+leap)return false;
	}
	return true;
}

int main(){
	int a,b,c;
	scanf("%d/%d/%d",&a,&b,&c);
	for(int i=19600101;i<20591231;i++){
		int year=i/10000;
		int month=i/100%100;
		int day=i%100;
		if(check(year,month,day)){
			if(year%100==a&&month==b&&day==c||month==a&&day==b&&year%100==c||day==a&&month==b&&year%100==c)
			printf("%d-%02d-%02d\n",year,month,day);
		}
	}
	return 0;
}

 5.分巧克力 

【问题描述】
儿童节那天有K位小朋友到小明家做客。小明拿出了珍藏的巧克力招待小朋友们。
小明一共有N块巧克力,其中第i块是H;× Wi的方格组成的长方形。为了公平起见,
小明需要从这N块巧克力中切出K块巧克力分给小朋友们。切出的巧克力需要满足:
1.形状是正方形,边长是整数;
2.大小相同;
例如一块6x5的巧克力可以切出6块2x2的巧克力或者2块3x3的巧克力。
当然小朋友们都希望得到的巧克力尽可能大,你能帮小明计算出最大的边长是多少么?
【输入描述】
第一行包含两个整数N, K (1≤N,K ≤105)。
以下N行每行包含两个整数H,Wi (1 ≤H, W;≤105)。
输入保证每位小朋友至少能获得一块1x1的巧克力。
【输出描述】
输出切出的正方形巧克力最大可能的边长。


#include <iostream>
using namespace std;
int L[100005];
int W[100005];
int main(){
	//1. 读入 N 和 K,N 表示物品个数,K 表示每个物品至少可以切分成的份数。
	//2. 分别读入 N 个物品的长度 L[i] 和宽度 W[i],存储到数组 L 和 W 中。
	//3. 声明变量 i 初始值为 10000,用于表示当前可切分的最大长度。
	int N,K;
	cin>>N>>K;
	for(int i=1;i<=N;i++)
	cin>>L[i]>>W[i];
	int i=10000;
	while(true){
		int sum=0,num1,num2;
		for(int j=1;j<=N;j++){
			num1=L[j]/i;
			num2=W[j]/i;
			sum+=num1*num2;
			/*
			对于第 j 个物品,先将其长度 L[j]、宽度 W[j] 分别除以 i 获取到能够切割成的
			数量 num1 和 num2,再将 num1 和 num2 乘起来得到该物品在 i 长度下最多可以切割成的块数。
			最后将每个物品能够 切割成的块数相加,得到总共可以切割成多少块,用 sum 变量进行累加,
			得到所有物品能够切割成的总块数。
			*/
		}
		if(sum>=K){
			break;
		}
		//如果总数量 sum 大于等于 K,则说明当前长度 i 是符合要求的,
		//可以跳出 while 循环;否则,将 i 的值减 1,继续进行二分查找。
		i--;
	}
	cout<<i;
	return 0;
}

持续分享...... 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

تچ快乐杂货店يچ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值