【刷题笔记】笔记二

  1. 奖卷数目(蓝桥真题)

题目描述:
五位数的开奖号码,去除含有”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类型方便操作
  1. 最小栈

题目链接
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).
  1. 栈的压入、弹出序列

题目链接
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();
    }
};
知识点:

  1. 逆波兰表达式(后缀表达式)的求解

题目链接
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,中缀怎么转换为后缀呢?操作数顺序不变;操作符要按照优先级重新排列,放到操作数后面去。

  1. 用栈实现队列

题目链表
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();

    }
};
  1. 数组中的第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 .
  1. 煤球数目(蓝桥真题)

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;
}
就是一个找规律的题目.
  1. 等差素数列(蓝桥真题)

直接暴力求解法:三层循环,遍历数组,枚举公差,记录个数.

#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;
}
这题直接暴力求解即可.
  1. 生日蜡烛(蓝桥真题)

这个就很简单了
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;
}
  1. 承压计算(蓝桥真题)

注意题目显示的金属块的重量计量单位很大,所以显示的数字很小.
电子秤的计量单位很小,所以数字很大.
我们在学习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

猜你喜欢

转载自blog.csdn.net/zxf123567/article/details/129384920