欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

头条2018实习生笔试

程序员文章站 2024-03-12 15:46:02
...

头条2018实习生笔试

输入解释:5是有5个用户,下一行输入5个用户对某一类文章的喜好程度k。3是有多少个查询,后面3行如2,4,5表示第二个用户到第4个用户之间有多少个用户的喜好程度为5. 输出这个数。

这个题的核心是用了一个map,key是每一种喜好程度值k,然后把同一个k的用户id放在一个vector里。即map<int, vector<int>>,每一个查询直接在要查询的喜好程度k相应的用户id数组中找。

#include <iostream>
#include <vector>
#include <map>
using namespace std;
int main()
{
    int n;
    cin >> n;
    vector<int> f(n, 0);
    map<int, vector<int>> m;
    for(int i = 0; i < n; ++i)
    {
        cin >> f[i];
        m[f[i]].push_back(i+1);
    }
    //查询
    int q;
    cin >> q;
    for(int i = 0; i < q; ++i)
    {
        int start, end, ques;
        cin >> start >> end >> ques;
        int count = 0;
        for(int j = 0; j < m[ques].size(); ++j)
        {
            if(m[ques][j] >= start && m[ques][j] <= end)
            {
                count++;
            }
        }
        cout << count << endl;
    }
}

头条2018实习生笔试

头条2018实习生笔试

这个题我也是用了同样的map,颜色号为key,把同一个颜色的不同珠子的序号放在一个vector里,即map<int, vector<int>>。对每一种颜色查看是否符合要求。先是两两检查,然后头尾检查,用到取模。

注意这个题我一开始把首位检查写在两两检查的for循环外面了,导致有些两两不符合要求首位也不符合要求的颜色被加了两次,调了很久才发现。。。

#include <iostream>
#include <vector>
#include <map>
using namespace std;
#include <fstream>
int main()
{
#ifdef debug
    ifstream cin("C:\\input.txt");
    ofstream cout("C:\\output.txt");
#endif // debug
    int res = 0;
    int n, m, c;
    cin >> n >> m >> c;
    map<int, vector<int>> mm;
    string s;
    for(int i = 0; i < n; ++i)
    {
        int colornum;
        cin >> colornum;
        for(int j = 0; j < colornum; ++j)
        {
            int x;
            cin >> x;
            mm[x].push_back(i+1);
        }
    }
    for(int i = 1; i <= c; ++i)
    {
        for(int j = 1; j <= mm[i].size()-1; ++j)
        {
            if(mm[i][j] <= mm[i][j-1] + m - 1)
            {
                res++;
                break;
            }
            if(j == mm[i].size()-1)
            {
                if((mm[i][j] + m) % n > mm[i][0])
                {
                    res++;
                    break;
                }
            }
        }

        //  错误原因:当前后两两比较的时候,如果发现错了,应该马上看下一个颜色,
        //  如果把头尾比较放在for的外面,那么在前后和头尾都有错的情况下,会重复加到结果集里
        //int j = mm[i].size()-1;
        //if(j >= 2)
        //{
        //    if((mm[i][j] + m) % n > mm[i][0])
        //    {
        //        res++;
        //        cout << i << "," << j << "-----(2)" << endl;
        //        for(int k = 0; k < mm[i].size(); ++k)
        //        {
        //            cout << mm[i][k] << " ";
        //        }
        //        cout << endl;
        //    }
        //}

    }
    cout << res << endl;
}

头条2018实习生笔试

这是一个动态规划题,对我来说有难度。我的做法还是定义了一个map,这次是让字母为key,把字母出现过的下标放在vector里。即map<char, vector<int>>。

例如a出现过的下标为0,4,5,9.要找出不少于m次操作的情况下,最多能把多少个a聚在一起,假设答案为res。换个思路想,找出把2个a聚在一起的最少操作次数,把3个a聚在一起的最少操作次数,4个a聚在一起的最少操作次数,len个a聚在一起的操作次数。如果这些操作次数小于m,那么可以更新res为len。

接下来的问题是,怎样找出把len个a聚在一起的最少操作次数?这里用动态规划。设下标的数组为pos[4],dp[4][4],其中dp[i][j]表示把pos[i]到pos[j]的a聚集起来需要的最少操作次数,初始化为0.  要操作次数最少,肯定是往中间聚。已知聚起来的长度为len。那么有dp[i][i+len-1] = dp[i+1][i+len-2] + pos[i+len-1]-pos[i]-len+1.

这个表达式是什么意思?比如现在要求出4个a聚集起来最少操作次数。已经知道把中间两个聚集起来的次数为dp[i+1][i+len-2],然后就是要把下标为0的a和下标为9的a聚到中间去。这两个a加起来需要移动的次数是,他俩中间的所有数字有多少个,减去已经排好了的a的个数。即pos[i+len-1] - pos[i] - 1 - (len - 2)。

#include <iostream>
#include <vector>
#include <map>
using namespace std;
int main()
{
    string s;
    int m;
    cin >> s >> m;
    int n = s.size();
    int res = 0;
    map<char, vector<int>> mm;
    for(int i = 0; i < n; ++i)
    {
        mm[s[i]].push_back(i);
    }
    for(auto a : mm)
    {
        //cout << a.first << endl;
        int idxnum = a.second.size();
        vector<vector<int>> dp(idxnum, vector<int>(idxnum, 0));
        for(int len = 2; len <= idxnum; ++len)
        {
            for(int i = 0; i + len - 1 < idxnum; ++i)
            {
                dp[i][i + len - 1] = dp[i+1][i+len-2] + (a.second)[i+len-1]
                                     -(a.second)[i] - len + 1;
                if(dp[i][i+len-1] <= m)
                    res = max(len, res);
            }
        }
    }
    cout << res << endl;
    return 0;
}