奖卷数目(蓝桥真题)
题目描述:
五位数的开奖号码,去除含有”4“的号码,还剩几个?
int fun()
{
int ret = 0;
for (int i = 10000; i < 100000; i++)
{
if (to_string(i).find('4') == string::npos)
{
ret++;
}
}
return ret;
}
int main()
{
cout<<fun();//52488
return 0;
}
知识点:
to_string() 将数字转换为string类型方便操作。
最小栈
题目链接
class MinStack {
public:
MinStack() {
//可以什么都不写为什么?
}
void push(int val) {
_st.push(val);
if(_minst.empty() || val <= _minst.top()){
//这里的两个判断条件不能换位置,为什么?
//第二个是小于等于,为什么?
_minst.push(val);
}
}
void pop() {
if(_st.top()==_minst.top()){
_minst.pop();
}
_st.pop();
}
int top() {
return _st.top();
}
int getMin() {
return _minst.top();
}
stack<int> _st;
stack<int> _minst;
};
知识点:
1,一个正常栈存入数据,一个记录最小值。
2,当st插入数据的时候和minst的栈顶比较,比他小,minst也push。
3,当st删除数据的时候也和minst的1栈顶比较,相等的时候,minst也pop。
4,算法的时间复杂的o(1),空间复杂度为o(n).
栈的压入、弹出序列
题目链接
class Solution {
public:
bool IsPopOrder(vector<int> pushV,vector<int> popV) {
size_t v2 = 0;
stack<int> st;
for(auto e : pushV)
{
st.push(e);
while( !st.empty() && st.top() == popV[v2])
{
++v2;
st.pop();
}
}
return v2 == popV.size();
}
};
知识点:
逆波兰表达式(后缀表达式)的求解
题目链接
class Solution {
public:
int evalRPN(vector<string>& tokens) {
stack<int> st;
//遍历每一个元素
for(auto e : tokens)
{
//判断是操作符还是操作数
if(e == "+" || e == "-" || e == "*" ||e == "/")
{
//遇到操作符,取出栈里面的前两个,运算(注意顺序)。
int right = st.top();
st.pop();
int left = st.top();
st.pop();
//注意switch(变量) ,这里的变量只能是整形或者char
switch (e[0])
{//区分是什么操作符
case '+':
st.push(left+right);
break;
case '-':
st.push(left-right);
break;
case '*':
st.push(left*right);
break;
case '/':
st.push(left/right);
break;
}
}
else
{
//遇到操作数,入栈
st.push(stoi(e));
}
}
return st.top();
}
};
知识点:
1,平常我们看到的是后缀表达式,后缀表达式对我们人类很友好,但是对于计算机很不友好。
所以需要将中缀表达式,改为后缀表达式,然后求解即可。
2,中缀怎么转换为后缀呢?操作数顺序不变;操作符要按照优先级重新排列,放到操作数后面去。
用栈实现队列
题目链表
class MyQueue {
stack<int> push_st;
stack<int> pop_st;
public:
MyQueue() {
//可以不写
}
void push(int x) {
push_st.push(x);
}
int pop() {
int ret = peek();
pop_st.pop();
return ret;
}
int peek() {
if(pop_st.empty()){
while(!push_st.empty()){
pop_st.push(push_st.top());
push_st.pop();
}
}
int ret = pop_st.top();
return ret;
}
bool empty() {
return pop_st.empty() && push_st.empty();
}
};
数组中的第K大的元素
题目链接
class Solution {
public:
int findKthLargest(vector<int>& nums, int k) {
//法一>
// priority_queue<int> pq(nums.begin(),nums.end());
// while(--k)
// {
// pq.pop();
// }
// return pq.top();
//上述的方法是建立一个 n 个数的大堆,然后pop (k-1) 次 ,取得第k大的数据.
//时间复杂的 o(n +klog(n)); 当n很大的时候效率不太高.
//法二>
priority_queue<int,vector<int>, greater<int>> pq;
//也可以 priority_queue<int, vector<int>,greater<int>> pq(nums.begin(),nums.begin()+k)
//这就是 vector迭代器的特殊使用,可以 进行+ 或者 - .
//但是list迭代器就没有重载,这些+ 和 - 只有 ++ 和--.
for(size_t i =0; i< nums.size(); i++){
if(i<k){
pq.push(nums[i]);
}
else{
if(pq.top() < nums[i])
{
pq.pop();
pq.push(nums[i]);
}
}
}
return pq.top();
//第二种就是建一个 k个数的小堆, 后面 n-k 个数字和堆顶比较,比堆顶大就pop->push
//第二种的时间复杂的 为 o(k + (n-k)logk) 如果 n>>k的时候很适合用第二种
}
};
知识点:
1,建立n个数的堆,时间复杂度为o(n)
2,典型的 top ,k问题,很好的利用了 priority_queue .
煤球数目(蓝桥真题)
int main()
{
int c = 1;
int add = 2;
int sum = 1;
for (int i = 0; i < 99; i++)
{
c += add;
++add;
sum += c;
}
cout << sum << endl;//171700
return 0;
}
就是一个找规律的题目.
等差素数列(蓝桥真题)
直接暴力求解法:三层循环,遍历数组,枚举公差,记录个数.
#define N 5000
bool fun(int n)
{
for (int i = 2; i < n / 2; i++){
if (n % i == 0) { return false; }
}
return true;
}
int main()
{
vector<int> v;
v.push_back(2);
v.push_back(3);
v.push_back(5);
v.push_back(7);
int nums = 11;
while(v.size() <= N){
if (fun(nums)){
v.push_back(nums);
}
nums+=2;
}
//遍历数组
int i = 0;
int count = 10;
for (auto e : v){
//公差
for ( i = 1; i < v.back() ; i++){
//计数遍历
count = 10;
int first = e;
while(--count){
if (fun(first + i)){
first += i;
}
else{
break;
}
}
if (count == 0) {
cout << i << endl;//210
return 0;
}
}
}
return 0;
}
这题直接暴力求解即可.
生日蜡烛(蓝桥真题)
这个就很简单了
int main()
{
//开始年份
for (int i = 0; i < 100; i++)
{
//当前年份
for (int j = i; j < 100; j++)
{
//等差数列求和
if ((i + j) *(j - i + 1)/2 == 236)
{
cout << i << endl;//26
}
}
}
return 0;
}
承压计算(蓝桥真题)
注意题目显示的金属块的重量计量单位很大,所以显示的数字很小.
电子秤的计量单位很小,所以数字很大.
我们在学习c/c++的时候 运算符/ 是整除, 例如7/2 == 3;
这个特性,会让我们计算的数据失去真实性.
怎么解决这个问题呢?
就需要定一个计量单位,且必须是2的30次方或者更大.然后对每个数据都乘上这个计量单位,
开始处理数据,然后排序.
步骤:
//1.将数据写入数组
//2.自上而下处理数据 a[i][j]*factor /2 ,计入a[i+1][j] 和a[i+1][j+1]
//3.循环处理1~n-1行
//4.对最后一行进行排序,查看最小值和题目给出的最小值的关系,决定最大值
#include<algorithm>
int main()
{
//假设计量单位的倍数
long long factor = 1;
factor <<= 29;//左移29位就是2的29次方
cout << factor << endl;
//1.将数据写入数组
vector<vector<long long>> arr;
arr.resize(30);
for (int i = 0; i < 30; i++)
{
arr[i].resize(30);
}
for (int i = 0; i < 29; i++)
{
for (int j = 0; j <= i; j++)
{
int nums = 0;
scanf_s("%d",&nums);
arr[i][j] = nums * factor;
//arr[i][j] = nums;
}
}
打印检验
//for (int i = 0; i < 29; i++)
//{
// for (int j = 0; j <= i; j++)
// {
//
// cout << arr[i][j] << ' ';
// }
// cout << endl;
//}
//2.自上而下处理数据 a[i][j]*factor /2 ,计入a[i+1][j] 和a[i+1][j+1]
for (int i = 0; i < 29; i++)
{ //3.循环处理1~n-1行
for (int j = 0; j <= i; j++)
{
long long nums = arr[i][j] / 2;
arr[i + 1][j] += nums;
arr[i + 1][j+1] += nums;
}
}
//4.对最后一行进行排序,查看最小值和题目给出的最小值的关系,决定最大值
sort(arr[29].begin(), arr[29].end());
for (int i = 0; i < 30; i++)
{
cout << arr[29][i] << endl;
}
return 0;
}
//给出输入的值 方便大家打印
//
//7
//5 8
//7 8 8
//9 2 7 2
//8 1 4 9 1
//8 1 8 8 4 1
//7 9 6 1 4 5 4
//5 6 5 5 6 9 5 6
//5 5 4 7 9 3 5 5 1
//7 5 7 9 7 4 7 3 3 1
//4 6 4 5 5 8 8 3 2 4 3
//1 1 3 3 1 6 6 5 5 4 4 2
//9 9 9 2 1 9 1 9 2 9 5 7 9
//4 3 3 7 7 9 3 6 1 3 8 8 3 7
//3 6 8 1 5 3 9 5 8 3 8 1 8 3 3
//8 3 2 3 3 5 5 8 5 4 2 8 6 7 6 9
//8 1 8 1 8 4 6 2 2 1 7 9 4 2 3 3 4
//2 8 4 2 2 9 9 2 8 3 4 9 6 3 9 4 6 9
//7 9 7 4 9 7 6 6 2 8 9 4 1 8 1 7 2 1 6
//9 2 8 6 4 2 7 9 5 4 1 2 5 1 7 3 9 8 3 3
//5 2 1 6 7 9 3 2 8 9 5 5 6 6 6 2 1 8 7 9 9
//6 7 1 8 8 7 5 3 6 5 4 7 3 4 6 7 8 1 3 2 7 4
//2 2 6 3 5 3 4 9 2 4 5 7 6 6 3 2 7 2 4 8 5 5 4
//7 4 4 5 8 3 3 8 1 8 6 3 2 1 6 2 6 4 6 3 8 2 9 6
//1 2 4 1 3 3 5 3 4 9 6 3 8 6 5 9 1 5 3 2 6 8 8 5 3
//2 2 7 9 3 3 2 8 6 9 8 4 4 9 5 8 2 6 3 4 8 4 9 3 8 8
//7 7 7 9 7 5 2 7 9 2 5 1 9 2 6 5 3 9 3 5 7 3 5 4 2 8 9
//7 7 6 6 8 7 5 5 8 2 4 7 7 4 7 2 6 9 2 1 8 2 9 8 5 7 3 6
//5 9 4 5 5 7 5 5 6 3 5 3 9 5 8 9 5 4 1 2 6 1 4 3 5 3 2 4 1
答案为:72665192664