【蓝桥杯 2020省赛b组】 前四道填空题

1.门牌制作

题目:

小蓝要为一条街的住户制作门牌号。
这条街一共有 2020 位住户,门牌号从 1 到 2020 编号。
小蓝制作门牌的方法是先制作 0 到 9 这几个数字字符,最后根据需要将字符粘贴到门牌上,例如门牌 1017 需要依次粘贴字符 1、0、1、7,即需要 1 个字符 0,2 个字符 1,1 个字符 7。
请问要制作所有的 1 到 2020 号门牌,总共需要多少个字符 2?

解题:

  思路:开个数组,遍历1~2020。记录每个数中出现数字最后打印即可.

代码:
#include <iostream>
using namespace std;
int m[10];

void div(int x){
  while(x){
    int t = x % 10;
    m[t] ++;
    x /= 10;
  }
}
int main()
{
  // 请在此输入您的代码
  for(int i=1;i<2021;i++){
    div(i);
  }
  cout<<m[2]<<endl;
  return 0;
}
结果
624

2.即约分数

题目:

如果一个分数的分子和分母的最大公约数是 1,这个分数称为既约分数。
例如 3 4 , 1 8 , 7 1 \frac{3}{4},\frac{1}{8},\frac{7}{1} 438117 都是既约分数。
请问,有多少个既约分数,分子和分母都是 1 到 2020 之间的整数(包括 1 和 2020)?

解题:

 思路:遍历1~2020,对分子分母求gcd,判断为1后累加答案.

代码:
#include <iostream>
using namespace std;
//gcd代码
int gcd(int a,int b){
  return b ? gcd(b,a%b) : a;
}

int main()
{
  // 请在此输入您的代码
  int res = 0;
  for(int i=1;i<2021;i++)
    for(int j=1;j<2021;j++)
      if(gcd(i,j) == 1)
        res ++;
  cout<<res<<endl;
  return 0;
}
答案:
2481215

3.蛇形填数

题目:

如下图所示,小明用从 1 开始的正整数“蛇形”填充无限大的矩阵。

1 2 6 7 15 ...
3 5 8 14 ...
4 9 13 ...
10 12 ...
11 ...
...

容易看出矩阵第二行第二列中的数是 5。请你计算矩阵中第 20 行第 20 列的数是多少?

  思路:可以控制遍历将蛇形矩阵继续走下去,我这里用的是找规律

22-> 5 ->3*3的等腰三角形的斜边中点
第33-> 13 ->5*5的等腰三角形的斜边中点
同理...
所以:
2 -> 3
3 -> 5
总结就是2*n + 1
而每个等腰三角形的右上角的点就是最大值点,其数值上等于这个三角形中数的个数.
所以 max(n) = 1 + 2 + ... + n
而最大值到中的距离就是 n- 1

根据找到的规律,很容易就可以写出代码:

#include <iostream>
using namespace std;
int main()
{
  int res = 0;
  for(int i=1;i<=20 * 2 - 1;i++){
    res += i;
  }
  res -= (20 -1);
  cout<<res<<endl;
  return 0;
}
答案:
761

4.跑步锻炼

题目:

小蓝每天都锻炼身体。
正常情况下,小蓝每天跑 1 千米。如果某天是周一或者月初(1 日),为了激励自己,小蓝要跑 2 千米。如果同时是周一或月初,小蓝也是跑 2 千米。
小蓝跑步已经坚持了很长时间,从 2000 年 1 月 1 日周六(含)到 2020 年 10 月 1 日周四(含)。请问这段时间小蓝总共跑步多少千米?

解题:

 思路:写一个nextDay函数,在主函数中判断该天的情况;

nextDay函数片段
int yy,mm,dd,mo;
int mon[] = {0,31,28,31,30,31,30,31,31,30,31,30,31};
void nextDay(){
  if(mo == 7){
    mo = 1;
  }else{
    mo ++;
  }
  if((yy % 4 == 0 && yy % 100 != 0) || yy % 400 == 0){
    mon[2] = 29;
  }else{
    mon[2] = 28;
  }
  if(dd == mon[mm]){
    dd = 1;
    mm ++;
  }else{
    dd ++;
  }
  if(mm == 13){
    mm = 1;
    yy ++;
  }
}
全部代码:
#include <iostream>
using namespace std;
int yy,mm,dd,mo;
int mon[] = {0,31,28,31,30,31,30,31,31,30,31,30,31};
void nextDay(){
  if(mo == 7){
    mo = 1;
  }else{
    mo ++;
  }
  if((yy % 4 == 0 && yy % 100 != 0) || yy % 400 == 0){
    mon[2] = 29;
  }else{
    mon[2] = 28;
  }
  if(dd == mon[mm]){
    dd = 1;
    mm ++;
  }else{
    dd ++;
  }
  if(mm == 13){
    mm = 1;
    yy ++;
  }
}

int main()
{
  // 请在此输入您的代码
  yy = 2000;
  mm = 1;
  dd = 1;
  mo = 6;
  int res = 0;
  while(true){
    if(yy == 2020 && mm == 10 && dd == 1 ){
      cout<<res + 2<<endl;
      break;
    }
    if(mo == 1 || dd == 1){
      res += 2;
    }else{
      res ++;
    }
    nextDay();
  }
  return 0;
}
答案:
8879

完结

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值