蓝桥杯——2018第九届C/C++真题[省赛][B组](一)

简介: 蓝桥杯——2018第九届C/C++真题[省赛][B组]

第几天


image.png

思路:这道题是蓝桥杯爱考的老题了,咱们可以通过电脑自带的计算器做也可以用excel做,最后我再提供一下代码吧

计算器

image.png

excel

image.png

代码:我把计算各种日期问题的模板代码放在这里,大家可以练习练习

#include<iostream>
using namespace std;
class Date {
public:
  int GetMonthDay(int year, int month) const
  {
    static int monthDayArray[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
    int day = monthDayArray[month];
    // 365天 5小时+
    if (month == 2 && ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)))
    {
      day += 1;
    }
    return day;
  }
  Date(int year, int month, int day)
  {
    _year = year;
    _month = month;
    _day = day;
    if (!(_year >= 0
      && (month > 0 && month < 13)
      && (day > 0 && day <= GetMonthDay(year, month))))
    {
      cout << "非法日期->";
      // this->Print();
      Print();
    }
  }
  void Print() const
  {
    cout << _year << "-" << _month << "-" << _day << endl;
  }
  bool operator>(const Date& d)  const
  {
    if (_year > d._year)
    {
      return true;
    }
    else if (_year == d._year && _month > d._month)
    {
      return true;
    }
    else if (_year == d._year && _month == d._month && _day > d._day)
    {
      return true;
    }
    else
    {
      return false;
    }
  }
  // d1 == d2
  bool operator==(const Date& d)  const
  {
    return _year == d._year
      && _month == d._month
      && _day == d._day;
  }
  // d1 < d2
  bool operator<(const Date& d)  const
  {
    return !(*this >= d);
  }
  // d1 >= d2
  bool operator>=(const Date& d)  const
  {
    return *this > d || *this == d;
  }
  bool operator<=(const Date& d)  const
  {
    return  !(*this > d);
  }
  bool operator!=(const Date& d)  const
  {
    return  !(*this == d);
  }
  // d1 += 100 
  Date& operator+=(int day)
  {
    if (day < 0)
    {
      return *this -= -day;
    }
    _day += day;
    while (_day > GetMonthDay(_year, _month))
    {
      _day -= GetMonthDay(_year, _month);
      ++_month;
      if (_month == 13)
      {
        _month = 1;
        _year++;
      }
    }
    return *this;
  }
  // d1 + 100
  Date operator+(int day)  const
  {
    Date ret(*this);
    //ret.operator+=(day);
    ret += day;
    return ret;
  }
  // d1 -= 10
  Date& operator-=(int day)
  {
    if (day < 0)
    {
      return *this += -day;
    }
    _day -= day;
    while (_day <= 0)
    {
      --_month;
      if (_month == 0)
      {
        --_year;
        _month = 12;
      }
      _day += GetMonthDay(_year, _month);
    }
    return *this;
  }
  // d1 - 10
  Date operator-(int day)  const
  {
    Date ret(*this);
    ret -= day;
    return ret;
  }
  // ++d1;
  Date& operator++()
  {
    *this += 1;
    return *this;
  }
  // d1++; 后置为了跟前置++,进行区分
  // 增加一下参数占位,跟前置++,构成函数重载
  Date operator++(int)
  {
    Date ret(*this);
    *this += 1;
    return ret;
  }
  // --d1;
  Date& operator--()
  {
    *this -= 1;
    return *this;
  }
  Date operator--(int)
  {
    Date ret(*this);
    *this -= 1;
    return ret;
  }
  // offerDay - today
  int operator-(const Date& d)  const
  {
    Date max = *this;
    Date min = d;
    int flag = 1;
    if (*this < d)
    {
      max = d;
      min = *this;
      flag = -1;
    }
    int count = 0;
    while (min != max)
    {
      ++min;
      ++count;
    }
    return count * flag;
  }
private:
  int _year;
  int _month;
  int _day;
};
int main()
{
  Date d1(2000, 1, 1);
  Date d2(2000, 5, 4);
  int count = d2 - d1;
  cout << count << endl;
  return 0;
}

答案:125

明码


image.png

4 0 4 0 4 0 4 32 -1 -16 4 32 4 32 4 32 4 32 4 32 8 32 8 32 16 34 16 34 32 30 -64 0
16 64 16 64 34 68 127 126 66 -124 67 4 66 4 66 -124 126 100 66 36 66 4 66 4 66 4 126 4 66 40 0 16
4 0 4 0 4 0 4 32 -1 -16 4 32 4 32 4 32 4 32 4 32 8 32 8 32 16 34 16 34 32 30 -64 0
0 -128 64 -128 48 -128 17 8 1 -4 2 8 8 80 16 64 32 64 -32 64 32 -96 32 -96 33 16 34 8 36 14 40 4
4 0 3 0 1 0 0 4 -1 -2 4 0 4 16 7 -8 4 16 4 16 4 16 8 16 8 16 16 16 32 -96 64 64
16 64 20 72 62 -4 73 32 5 16 1 0 63 -8 1 0 -1 -2 0 64 0 80 63 -8 8 64 4 64 1 64 0 -128
0 16 63 -8 1 0 1 0 1 0 1 4 -1 -2 1 0 1 0 1 0 1 0 1 0 1 0 1 0 5 0 2 0
2 0 2 0 7 -16 8 32 24 64 37 -128 2 -128 12 -128 113 -4 2 8 12 16 18 32 33 -64 1 0 14 0 112 0
1 0 1 0 1 0 9 32 9 16 17 12 17 4 33 16 65 16 1 32 1 64 0 -128 1 0 2 0 12 0 112 0
0 0 0 0 7 -16 24 24 48 12 56 12 0 56 0 -32 0 -64 0 -128 0 0 0 0 1 -128 3 -64 1 -128 0 0

思路:主要看懂题目,共10行,每行32个十进制数字,一行代表一个汉字,就是先要把这些十进制转化为二进制,若为负数则转换为补码(负数的二进制就是负数的补码),输入直接复制即可,运行结果为“九的九次方等于多少?”最后再根据要求求出整数答案。

推荐博客:bitset用法小结 - 自为风月马前卒 - 博客园

#include<iostream>
#include<bitset>
using namespace std;
int main() {
    int n, m;
    while (cin >> n >> m) {
        bitset<8> t;//t为二进制8位    biset<length> t
        t = n;//将n赋给t,即将n转化为8位二进制 
        cout << t;//输出n的8位二进制 
        t = m;//将m赋给t,即将n转化为8位二进制 
        cout << t << endl;//输出n的8位二进制 
    }
    return 0;
}

这个就是主代码了;可以看一下运行结果:

image.png

这样并不能看的很清楚,我们再稍微改进一下

代码:

#include<iostream>
#include<bitset>
#include<string>
using namespace std;
int main()
{
  int n, m;
  int len;
  string temp;
  while (cin >> n >> m)
  {
    bitset<8> t;
    t = n;
    temp = t.to_string();
     len = temp.size();
    for (int i = 0; i < len; i++)
    {
      if (temp[i] == '0')
      {
        cout << " ";
      }
      else {
        cout << "*";
      }
    }
    t = m;
    temp = t.to_string();
     len = temp.size();
    for (int i = 0; i < len; i++)
    {
      if (temp[i] == '0')
      {
        cout << " ";
       }
      else {
        cout << "*";
      }
    }
    cout << endl;
  }
  return 0;
}

image.png

答案:387420489

乘积尾零


image.png

思路:这个题不能直接乘,我们要想办法转化,


两个数相乘


2*5=10, 2*1*5*1=10,          有一个2,一个5;


4*25=100,2*2*5*5=10        有两个2,二个5;


8*125,2*2*2*5*5*5=1000   有三个2,三个5;


求尾零的个数就是求2与5的对数(即两者中最小数为两者的对数)


代码:

#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
  int num[10 * 10] = { 5650, 4542, 3554, 473, 946, 4114, 3871, 9073, 90, 4329,
    2758, 7949, 6113, 5659, 5245, 7432, 3051, 4434, 6704, 3594,
    9937, 1173, 6866, 3397, 4759, 7557, 3070, 2287, 1453, 9899,
    1486, 5722, 3135, 1170, 4014, 5510, 5120, 729, 2880, 9019,
    2049, 698, 4582, 4346, 4427, 646, 9742, 7340, 1230, 7683,
    5693, 7015, 6887, 7381, 4172, 4341, 2909, 2027, 7355, 5649,
    6701, 6645, 1671, 5978, 2704, 9926, 295, 3125, 3878, 6785,
    2066, 4247, 4800, 1578, 6652, 4616, 1113, 6205, 3264, 2915,
    3966, 5291, 2904, 1285, 2193, 1428, 2265, 8730, 9436, 7074,
    689, 5510, 8243, 6114, 337, 4096, 8199, 7313, 3685, 211 };
  int count_2 = 0, count_5 = 0;
  for (int i = 0; i < sizeof(num) / sizeof(int); i++)
  {
    int temp = num[i];
    while (temp % 2 == 0)
    {
      count_2++;
      temp /= 2;
    }
    while (temp % 5 == 0)
    {
      count_5++;
      temp /= 5;
    }
  }
  cout << min(count_2, count_5) << endl;
  return 0;
}

答案:31

测试次数


image.png

思路:


这里有两种解法 动态规划 和 手算 后一种方法比较好理解就不做解释 主要来解决一下动态规划


首先要理解一下dp[i][j] i表示手机数 j表示楼层数 dp[][]就表示有i部手机j层楼的情况下 最坏运气下需要测试的次数


我们先假设不采取最佳策略 即没一个j层的楼房 我们都要摔j次 但是当手机只有一部的情况时 这其实就是最佳策略,那么我们就可以逐渐往上拓展


假设我们已经把 i-1部手机对于所有楼层的次数已经找出,现在我们来求有i部手机时的测试次数


为此我们需要遍历 当前之前的楼层k(1~j-1)假设在k层摔坏 我们就选取i-1部手机对于k-1层楼房的最坏情况dp[i-1][k-1]+1


假如在k层没有摔坏 那么我们就可以选取i部手机对于剩下j-k层的最坏情况 dp[i][j-k]+1


由于是最坏情况 我们需要在两者之间取最大值,但我们又是采取的最佳策略 所以对于之前的非最佳策略 我们需要取最小值,即:


dp[i][j]=min(dp[i][j],max(dp[i-1][k-1],dp[i][j-k])+1);


代码

#include<iostream>
using namespace std;
int dp[5][1007];
int main()
{
        ios::sync_with_stdio(false);
        for (int i = 1; i <= 3; i++)
            for (int j = 1; j <= 1000; j++)
                dp[i][j] = j;
        for (int i = 1; i <= 1000; i++)
            for (int j = 2; j <= 3; j++) {
                for (int k = 1; k < i; k++)
                    dp[j][i] = min(dp[j][i], max(dp[j - 1][k - 1], dp[j][i - k]) + 1);
            }
        cout << dp[3][1000] << endl;
        return 0;
}

答案:19

快速排序


以下代码可以从数组a[]中找出第k小的元素。

它使用了类似快速排序中的分治算法,期望时间复杂度是O(N)的。

请仔细阅读分析源码,填写划线部分缺失的内容。

#include <stdio.h>
int quick_select(int a[], int l, int r, int k) {
  int p = rand() % (r - l + 1) + l;
  int x = a[p];
  {int t = a[p]; a[p] = a[r]; a[r] = t;}
  int i = l, j = r;
  while(i < j) {
    while(i < j && a[i] < x) i++;
    if(i < j) {
      a[j] = a[i];
      j--;
    }
    while(i < j && a[j] > x) j--;
    if(i < j) {
      a[i] = a[j];
      i++;
    }
  }
  a[i] = x;
  p = i;
  if(i - l + 1 == k) return a[i];
  if(i - l + 1 < k) return quick_select( _____________________________ ); //填空
  else return quick_select(a, l, i - 1, k);
}
int main()
{
  int a[] = {1, 4, 2, 8, 5, 7, 23, 58, 16, 27, 55, 13, 26, 24, 12};
  printf("%d\n", quick_select(a, 0, 14, 5));
  return 0;
}

k就再向右半部分,此时就不是第k小的了,不然就向左边去找第k小的数.

答案:(a,i+1,r,k-(i-l+1));

相关文章
|
9天前
|
测试技术 C++
[蓝桥杯 2023 省 B] 冶炼金属(c++)
[蓝桥杯 2023 省 B] 冶炼金属(c++)
21 0
|
2月前
|
Java C++ Python
第十四届蓝桥杯集训——练习解题阶段(无序阶段)-ALGO-456 求链表各节点的平均值(C++解法)
第十四届蓝桥杯集训——练习解题阶段(无序阶段)-ALGO-456 求链表各节点的平均值(C++解法)
29 0
|
2月前
|
Java 数据安全/隐私保护 C++
第十四届蓝桥杯集训——练习解题阶段(无序阶段)-ALGO-193 Password Suspects(C++&Java)
第十四届蓝桥杯集训——练习解题阶段(无序阶段)-ALGO-193 Password Suspects(C++&Java)
20 1
|
2月前
|
Java C++ Python
第十四届蓝桥杯集训——练习解题阶段(无序阶段)-ALGO-161 Abbott’s Revenge(C++写法)
第十四届蓝桥杯集训——练习解题阶段(无序阶段)-ALGO-161 Abbott’s Revenge(C++写法)
125 42
|
2月前
|
人工智能 测试技术 C++
第十五届蓝桥杯模拟赛B组(第二期)C++
第十五届蓝桥杯模拟赛B组(第二期)C++
91 0
第十五届蓝桥杯模拟赛B组(第二期)C++
|
3月前
|
人工智能 测试技术 C++
蓝桥杯15届第二次模拟赛C/C++详解
蓝桥杯15届第二次模拟赛C/C++详解
103 0
|
3月前
|
C++
蓝桥杯15届第二次模拟C++
蓝桥杯15届第二次模拟C++
31 0
|
3天前
|
存储 编译器 C语言
c++的学习之路:5、类和对象(1)
c++的学习之路:5、类和对象(1)
19 0
|
3天前
|
C++
c++的学习之路:7、类和对象(3)
c++的学习之路:7、类和对象(3)
19 0
|
2天前
|
设计模式 Java C++
【C++高阶(八)】单例模式&特殊类的设计
【C++高阶(八)】单例模式&特殊类的设计