2021年第十二届蓝桥杯省赛真题 (C/C++ 大学B组)

题目A:空间(5分)

  • 题目描述
    小蓝准备用256MB 的内存空间开一个数组,数组的每个元素都是 32 位二进制整数,如果不考虑程序占用的空间和维护内存需要的辅助空间,请问256MB 的空间可以存储多少个32 位二进制整数?
    答案提交
      这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。67108864

  • 题目分析
    计算器:
    1MB=1024KB=1024 * 1024B=1024 * 1024 * 8bit
    256 * 1024 * 1024*8/32=67108864

  • 题目代码

#include <stdio.h>
int main() {
    printf("%d", 256 >> 2 << 20);
}

题目B:卡片(5分)

  • 题目描述
    小蓝有很多数字卡片,每张卡片上都是数字0到9。
    小蓝准备用这些卡片来拼一些数,他想从1开始拼出正整数,每拼一个,就保存起来,卡片就不能用来拼其它数了。
    小蓝想知道自己能从1拼到多少。
    例如,当小蓝有30张卡片,其中0到9各3张,则小蓝可以拼出1到10,但是拼11时卡片1已经只有一张了,不够拼出11。
    现在小蓝手里有0到9的卡片各2021张,共20210张,请问小蓝可以从1拼到多少?3181
    提示:建议使用计算机编程解决问题。

  • 题目分析

  • 题目代码(1)

#include <stdio.h>

int n, ans, cnt;

int main() {
    while (1) {
       n = ans;
       while (n) {
           if (n % 10 == 1) cnt++;
           n /= 10;
       }
       if (cnt < 2021) ans++;
       else break;
    }
    printf("%d", ans);
}
  • 题目代码(2)
#include <algorithm>
#include <cstring>
#include <iostream>

using namespace std;
int s[10];

bool check(int x) {
  while (x) {
    int t = x % 10;
    x = x / 10;
    if (--s[t] < 0) return false;
  }
  return true;
}

int main() {
  for (int i = 0; i < 10; i++) s[i] = 2021;
  for (int i = 1;; i++) {
    if (!check(i)) {
      //检查该数是否已经用完,不够用即最后一个数为所求的数
      cout << i - 1 << endl;
      return 0;
    }
  }
}

题目C:直线(10分)

  • 题目描述
    在平面直角坐标系中,两点可以确定一条直线。如果有多点在一条直线上, 那么这些点中任意两点确定的直线是同一条。
    给定平面上 2 × 3 个整点(x, y)|0 ≤ x < 2, 0 ≤ y < 3, x ∈ Z, y ∈ Z​,即横坐标 是 0 到 1 (包含 0 和 1) 之间的整数、纵坐标是 0 到 2 (包含 0 和 2) 之间的整数的点。这些点一共确定了 11 条不同的直线。
    给定平面上 20 × 21个整点 (x, y)|0 ≤ x < 20, 0 ≤ y < 21, x ∈ Z, y ∈ Z,即横 坐标是 0 到 19 (包含 0 和 19) 之间的整数、纵坐标是 0 到 20 (包含 0 和 20​) 之 间的整数的点。
    请问这些点一共确定了多少条不同的直线。40257

  • 题目分析

  • 题目代码

//直线
//大致思路:依次枚举各个点,每两个点生成对应的斜率和截距。最后看有多少个不同的组合,即有多少条不同的直线
//注意事项:类型为double的两个数值a和b,即使数值相同,对应的double值也有可能不同,故在cpp中比较两个double值应判断其abs之差是否在很小的一个范围之内,例如1e-8
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<math.h>
using namespace std;
// 直线的最大数
const int N=200000;
int n=0;
struct Line
{
    double k;
    double b;
    // 结构体内嵌排序函数
    // 直接写比较函数是裸的len表示当前的值,如果len<a.len,那么就是从小到大排序。
    // 括号中的const表示参数a对象不会被修改,最后的const表明调用函数对象不会被修改!
    // sort默认为从小到大排序,优先队列默认为从大到小。
    bool operator < (const Line& t) const  //重载<操作符。可以对两个node使用<操作符进行比较
    {
        // k不同的话,k小的在前
        if(k!=t.k) return k<t.k;
        // k相同的话,b小的在前
        return b<t.b;
    }
}l[N];

int main()
{
    //枚举一下所有的点对
    for(int x1=0;x1<20;x1++)
    {
        for(int y1=0;y1<21;y1++)
        {
            for(int x2=0;x2<20;x2++)
            {
                for(int y2=0;y2<21;y2++)
                if(x1!=x2)//避免斜率不存在的情况,总共20条竖线
                {
                    double k=(double)(y2-y1)/(x2-x1);
                    double b=y2-k*x2;
                    // l[n].k=k;
                    // l[n].b=b;
                    // n++;
                    //数对存下来
                    l[n++]={k,b};
                }
            }
        }
    }
    sort(l,l+n);

    int res=1;
    for(int i=1;i<n;i++)
        // 找出截率和斜率不等的就是不同数
    {
        if(fabs(l[i].k-l[i-1].k)>1e-8||fabs(l[i].b-l[i-1].b)>1e-8)
        res++;

    }
    cout<<res+20<<endl;
    return 0;
}

结构体排序的两种方法

一、自定义比较函数

#include <iostream>
#include <algorithm>
using namespace std;
struct N
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值