搜狗2020校招(后端)笔试第一场

写了两道题

第一题

链接:https://www.nowcoder.com/questionTerminal/40223a1cd2a24b96aaff958e516c49fc
来源:牛客网
 

关联容器map保存<key, value>数据,能通过key快速存储或查找记录。请设计一个map,能够满足以下要求:

1. map的容量size是一个固定值N,即map最多保存N个<key, value>记录;

2. map insert一个<key, value>前,首先判断这个key是否已经在map中存在:

   1) 如果存在:记这个已存在的记录为<key, old_value>,若old_value<value,则把old_value更新为value;否则,不做更新。

   2) 如果不存在:

       若size<N,则执行map的insert,保存这个<key, value>,且size+=1;

       若size==N,先淘汰掉一个更新时间最早的记录,再执行map的insert,保存这个<key, value>,size保持为N不变。

说明:记录的更新时间默认为其被insert进map的时间,之后的某一时刻T,如果这个记录的value被更新,那么,该记录的更新时间就变为T。

 

输入描述:

第一行是map的最大size N(N<=200000),之后每一行都为"Key Value",其中Key为一个字符串(长度<16),Value为无符号整数(unsigned int),Key和Value之间用空格分隔。


 

输出描述:

输出为map insert的过程中被淘汰掉的记录(不输出value被更新的记录),每行为"Key Value", 和输入文件的"Key Value"格式相同。

示例1

输入

2
10_123_50_A0 1566918054
10_123_50_A1 1566918054
10_123_50_A1 1566918055
10_123_50_A3 1566918055
10_123_50_A4 1566918056

输出

10_123_50_A0 1566918054
10_123_50_A1 1566918055

 

题解:LRU缓存机制,直接用unordered_map + list即可

#include <bits/stdc++.h>

using namespace std;

struct KVNode {
  string key;
  unsigned int value;
  KVNode(string _key, unsigned int _value) : key(_key), value(_value) {}
};

class Map {
private:
  int n;
  unordered_map<string,list<KVNode>::iterator> _mp;
  list<KVNode> _list;
  bool isExists(const string& key) {
    return _mp.find(key) != _mp.end();
  }
public:
  Map(int _n) : n(_n) {}
  void Insert(string key, unsigned int val, tuple<bool,string,unsigned int>& res) {
    if (_mp.count(key) != 0) {
      if (_mp[key]->value < val) {
        _list.erase(_mp[key]);
        _mp.erase(key);
        _list.push_front(KVNode(key, val));
        _mp[key] = _list.begin();
      }
      res = make_tuple(false, "", 1);
    } else {
      if ((int)_mp.size() == n) {
        auto node = _list.back();
        _list.pop_back();
        _mp.erase(node.key);
        res = make_tuple(true, node.key, node.value);
        _list.push_front(KVNode(key, val));
        _mp[key] = _list.begin();
      } else {
        _list.push_front(KVNode(key, val));
        _mp[key] = _list.begin();
        res = make_tuple(false, "", 1);
      }
    }
  }
};

int main() {
  int n;
  scanf("%d", &n);
  Map *mp = new Map(n);
  string key;
  unsigned int val;
  tuple<bool, string, unsigned int> res;
  while (cin >> key >> val) {
    mp->Insert(key, val, res);
    if (get<0>(res)) {
      cout << get<1>(res) << " " << get<2>(res) << endl;
    }
  }
  return 0;
}

第二题不会

 

第三题:

链接:https://www.nowcoder.com/questionTerminal/412fcc0b545244e188348338d36cde93
来源:牛客网
 

【题干描述】:

我们共有n台服务器,每台服务器可以和若干个子服务器传输数据,n台服务器组成一个树状结构。

现在要将一份数据从root节点开始分发给所有服务器。

一次数据传输需要一个小时时间,

一个节点可以同时对k个儿子节点进行并行传输,

不同节点可以并行分发。

问,全部分发完成,最短需要多少小时?

 

【示例】:

当共有5台服务器,其树状结构为

       0

     /     \

   1      2

  /   \

 3    4

假设每一台服务器同时可以对1个儿子节点(k=1)并行传输,最优的数据传输过程示例如下:

    第一个小时,0 -> 1;

    第二个小时,1->3 & 0->2;

    第三个小时,1 -> 4;

所以当k=1时,全部分发完成最短需要3个小时。

假设每一台服务器同时可以对2个儿子节点(k=2)并行传输,最优的数据传输过程示例如下:

    第一个小时,0 -> 1 & 0 -> 2;

    第二个小时,1 -> 3 & 1 -> 4;

所以当k=2时,全部分发完成最短需要2个小时。

 

输入描述:

首行输入包含两个参数,分别表示每台服务器允许k个子节点并行传输,以及剩余输入行数。
其他行用于服务器树状结构描述,每一行表示一个父节点以及父节点对应的所有子节点。每一行都通过空格符分割不同数字,第一位数字为父节点及其所有子节点个数,第二位数字为父节点编号,其他数字为对应的子节点编号。


 

输出描述:

输出全部服务器分发完成,需要的最短时间。

示例1

输入

1 2
3 0 1 2
2 1 3

输出

2

题解:贪心+dfs,父节点每次分发的时候先分发给那些分发完所需时间最长的子节点分发。

#include <bits/stdc++.h>

using namespace std;

const int N = 1000005;

vector<int> Tree[N];
int Indegree[N];

int dfs(int u, int k) {
  if (Tree[u].empty()) {
    return 0;
  }
  vector<int> foo;
  for (int v : Tree[u]) {
    foo.push_back(dfs(v, k));
  }
  sort(foo.begin(), foo.end(), [&](int x, int y) {return x > y;});
  int res = 0;
  for (int i = 0; i < (int)foo.size(); i++) {
    res = max(res, (i + 1 + k - 1) / k + foo[i]);
  }
  return res;
}

int main() {
  int k, n;
  int sz = 0;
  scanf("%d %d", &k, &n);
  for (int i = 0; i < n; i++) {
    int tt;
    int pre;
    scanf("%d %d", &tt, &pre);
    sz = max(sz, pre);
    while (--tt) {
      int u;
      scanf("%d", &u);
      Tree[pre].push_back(u);
      Indegree[u] = 1;
      sz = max(sz, u);
    }
  }
  int root = 0;
  for (int i = 0; i <= sz; i++) {
    if (Indegree[i] == 0) {
      root = i;
      break;
    }
  }
  cout << dfs(root, k) << endl;
  return 0;
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值