第几天
思路:这道题是蓝桥杯爱考的老题了,咱们可以通过电脑自带的计算器做也可以用excel做,最后我再提供一下代码吧
计算器
excel
代码:我把计算各种日期问题的模板代码放在这里,大家可以练习练习
#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
明码
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; }
这个就是主代码了;可以看一下运行结果:
这样并不能看的很清楚,我们再稍微改进一下
代码:
#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; }
答案:387420489
乘积尾零
思路:这个题不能直接乘,我们要想办法转化,
两个数相乘
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
测试次数
思路:
这里有两种解法 动态规划 和 手算 后一种方法比较好理解就不做解释 主要来解决一下动态规划
首先要理解一下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));