笔试模拟 day1

观前提醒:

笔试所有系列文章均是记录本人的笔试题思路与代码,从中得到的启发和从别人题解的学习到的地方,所以关于题目的解答,只是以本人能读懂为目标,如果大家觉得看不懂,那是正常的。如果对本文的某些知识有不同的观点,欢迎讨论。

题目链接:

第一题:[NOIP2010]数字统计_牛客题霸_牛客网

第二题:两个数组的交集_牛客题霸_牛客网

第三题:点击消除_牛客题霸_牛客网

---------------------------------------------------我是分割线---------------------------------------------------------------

---------------------------------------------------我是分割线---------------------------------------------------------------

---------------------------------------------------我是分割线---------------------------------------------------------------

---------------------------------------------------我是分割线---------------------------------------------------------------

---------------------------------------------------我是分割线---------------------------------------------------------------

第一题

思路: 

本题要求统计“2”的数量,给出了一个数据范围。

很明显,最简单的想法是,

1)遍历每一个数,然后统计每个数的“2”的个数,再相加。

那么第二个考虑的问题是,怎么统计每个数的“2”的个数。

这里的思路是遍历的每个数字的每一位,如何遍历呢。

2)两种办法,一、将数字num%10就可以得出每一位,二、将数字转变为字符串,然后遍历字符串就好。 

第一题 代码:

#方法一,取模遍历
#include <iostream>
using namespace std;

int main() {
    int a=0,b=0;
    scanf("%d %d",&a,&b);
    int count=0; //负责统计二的个数
    for(int i=a;i<=b;i++)
    {
        int y=i;//不要直接使用i会导致循环出现问题
        while(y != 0)
        {
            int x=y%10; //记录下i的每个位置上的数字
            if(x == 2) count++;
            y/=10;
        }
    }
    printf("%d\n",count);
    return 0;
}

#方法二,字符遍历
#include <iostream>
#include <string>
using namespace std;

int main() {
    int a=0,b=0;
    scanf("%d %d",&a,&b);
    string str;
    int count=0;
    for(int i=a;i<=b;i++)
    {
        str=to_string(i);
        for(int j=0;j<str.size();j++)
        {
            if(str[j] == '2') count++;
        }
    }
    printf("%d\n",count);
    return 0;
}

 

---------------------------------------------------我是分割线---------------------------------------------------------------

---------------------------------------------------我是分割线---------------------------------------------------------------

---------------------------------------------------我是分割线---------------------------------------------------------------

 

第二题

思路 

  本题要求求两个数组的公共部分

脑子的第一想法是,将两个数组遍历一边,但是这也导致了另一个问题,如果数组中有重复元素该怎么办。

例如下图所示

如果是按照,只遍历一边的想法,很有可能我们的最终结果是[2,2]。但是牛客的要求是【2】说明我们要去重。

1)对原先的两个数组去重

可如何去重呢?也很简单使用我们的数据结构---哈希表不就好了吗。是使用自带去重功能的set还是map都可以,不过这道题的取值范围比较小,我们可以通过数组模拟哈希。

2)使用数据结构的哈希,或者是使用数组模拟

第二题 代码 :

#使用STL的set去重
class Solution {
public:
   
    vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
        set<int> s1, s2;
        vector<int> ret;
        for(auto& e:nums1)
            s1.insert(e);
        for(auto& e:nums2)
           s2.insert(e);
           //遍历元素较少的set,提高效率
           if(s1.size() <s2.size())
            {
                for(auto& e:s1)
                {
                     if(s2.count(e))
                    {
                        ret.push_back(e);
                    }
                }
            }
            else
            {   
                for(auto& e:s2)
                {
                    if(s1.count(e))
                    {
                        ret.push_back(e);
                    }
                }
            }
            return ret;

    }
};


class Solution {
    //这里一定要初始化,牛客的数组初始化与力扣的初始化不一样,你不初始化,它默认是随机值。
    bool hash[1001]={false};
public:
    vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
    vector<int> ret;
    for(auto& e:nums1)
    {
       hash[e]=true; 
    }

    for(int i=0;i<nums2.size();i++)
    {
        if(hash[nums2[i]])
        {
            ret.push_back(nums2[i]);
            hash[nums2[i]]=false;//这一步就是相对于去重了,一个数字只使用一次。
        }
    }
    return ret;
    }
};

---------------------------------------------------我是分割线---------------------------------------------------------------

---------------------------------------------------我是分割线---------------------------------------------------------------

---------------------------------------------------我是分割线---------------------------------------------------------------

第三题

思路

我们模拟一遍这种消除字符串的行为,第一次外面来了个“a”,由于字符串为空,不会消除,字符进入字符串中,第二次来了个“b”没影响,第三次来了个“b”,但是这次我们字符串未是一个“b”(不是a了),所以b消除了。我们回顾这个过程发现这个过程是不是与我们的栈十分相似,我们不就可以使用栈了模拟这个数据结构吗?

1)使用栈模拟这个过程

 同时我们发现这个过程只是需要后进先出的特性,所以我们也可以选择使用数组去模拟数组,来完成这个过程。使用栈模拟后,消除的结果存放在栈中,我们需要做的是将栈的元素导出。

2)遍历栈,构建一个新的返回值

第三题 代码

#include <iostream>
#include <string>
#include<vector>
using namespace std;

int main() {
   string str="";
    cin>>str;
    int n=str.size();
    vector<char> sc;
    for(int i=0;i<n;i++)
    {
        if(sc.empty()) //数组为空,肯定不能匹配,直接进入
        {
            sc.push_back(str[i]);
        }
        else if(sc.back() == str[i])
        {
            sc.pop_back();
        }
        else {
            sc.push_back(str[i]);
        }
    }
    str.clear();
    for(auto& e:sc) str+=e;
    if(str.size())
    printf("%s\n",str.c_str());
    else
    {
        printf("0\n");
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值