2020.08.08 网易秋招算法岗笔试

每个人的题目可能是不一样的。


T1:把数组里的数拆成素数,要求统计数组中所有数的素数个数和。
贪心拆成2然后统计即可,注意1E6个数,每个数最大为1E9,答案会爆int.
#include <bits/stdc++.h>

using namespace std;
using LL = long long;
using pii = pair<LL, LL>;

const int maxn = 1001000;
int n;
int a[maxn];

signed main() {
  // freopen("in", "r", stdin);
  // freopen("out", "w", stdout);
  while (~scanf("%d", &n)) {
    LL tot = 0;
    for (int i = 1; i <= n; i++) {
      scanf("%d", &a[i]);
      tot += a[i] / 2;
    }
    printf("%lld\n", tot);
  }
  return 0;
}


T2:n个人排队操作,每个人花费时间为ai,也可以第i个人和前一个人一起操作花费时间为bi,问最少花费时间并且转成要求格式。
DP,f(i,j)维护到第i个人按照j操作时的总最少花费,转移看代码;转换格式感觉数据弱了,不表了。
#include <bits/stdc++.h>

using namespace std;
using LL = long long;
using pii = pair<LL, LL>;

const int maxn = 2020;
int n;
int a[maxn], b[maxn];
int f[maxn][2];

void gao(int second) {
	int minute = second / 60;
	second %= 60;
	int hour = minute / 60;
	minute %= 60;
	hour += 8;
	string suf = (hour <= 12 ? "am" : "pm");
	if (hour > 12) hour -= 12;
	printf("%02d:%02d:%02d %s\n", hour, minute, second, suf.c_str());
}

signed main() {
  // freopen("in", "r", stdin);
  // freopen("out", "w", stdout);
  int T;
  scanf("%d", &T);
  while (T--) {
    scanf("%d", &n);
    memset(a, 0, sizeof a);
    memset(b, 0, sizeof b);
    memset(f, 0x7f, sizeof f);
    for (int i = 1; i <= n; i++) {
      scanf("%d", &a[i]);
    }
    for (int i = 2; i <= n; i++) {
    	scanf("%d", &b[i]);
    }
    f[0][0] = f[0][1] = 0;
    f[1][0] = f[1][1] = a[1];
    for (int i = 2; i <= n; i++) {
    	f[i][0] = min({f[i][0], f[i - 1][0] + a[i], f[i - 1][1] + a[i]});
    	f[i][1] = min({f[i][1], f[i - 2][0] + b[i], f[i - 2][1] + b[i]});
    }
    gao(min(f[n][0], f[n][1]));

  }
  return 0;
}


T3:n个数字,扔掉任意个,然后再把剩下的数拆成两组和相同的数,问扔掉数字的最小和。
爆搜3^n
#include <bits/stdc++.h>

using namespace std;
using LL = long long;
using pii = pair<LL, LL>;

const int maxn = 16;
int n;
int a[maxn];
int ret = INT_MAX;

void dfs(int id, int l, int r, int drop) {
  if (id == n + 1) {
    if (l == r) {
      ret = min(ret, drop);
    }
    return;
  }
  dfs(id + 1, l + a[id], r, drop);
  dfs(id + 1, l, r + a[id], drop);
  dfs(id + 1, l, r, drop + a[id]);
}


signed main() {
  // freopen("in", "r", stdin);
  // freopen("out", "w", stdout);
  int T;
  scanf("%d", &T);
  while (T--) {
    scanf("%d", &n);
    for (int i = 1; i <= n; i++) {
      scanf("%d", &a[i]);
    }
    ret = INT_MAX;
    dfs(1, 0, 0, 0);
    printf("%d\n", ret);
  }
  return 0;
}



T4:题意翻译一下就是给一个有向图,问有多少点对可以互相可达。
tarjan求强连通分量,缩点后统计每个强连通分量中的点数,答案就是sum((k-1)*k/2),k为每个强连通分量中的点数,注意开LL.
#include <bits/stdc++.h>

using namespace std;
using LL = long long;
using pii = pair<int, int>;

const int maxn = 50050;
const int maxm = 600600;

typedef struct Edge {
  int u;
  int v;
  int next;
  Edge() { next = -1; }
}Edge;

int head[maxn], ecnt;
Edge edge[maxm];
int n, m;

int bcnt, dindex;
int dfn[maxn], low[maxn];
int stk[maxn], top;
int belong[maxn];
int in[maxn], out[maxn];
bool instk[maxn];

void init() {
  memset(edge, 0, sizeof(edge));
  memset(head, -1, sizeof(head));
  memset(instk, 0, sizeof(instk));
  memset(dfn, 0, sizeof(dfn));
  memset(low, 0, sizeof(low));
  memset(belong, 0, sizeof(belong));
  memset(in, 0, sizeof(in));
  memset(out, 0, sizeof(out));
  ecnt = top = bcnt = dindex = 0;
}

void adde(int uu, int vv) {
  edge[ecnt].u = uu;
  edge[ecnt].v = vv;
  edge[ecnt].next = head[uu];
  head[uu] = ecnt++;
}

void tarjan(int u) {
  int v = u;
  dfn[u] = low[u] = ++dindex;
  stk[++top] = u;
  instk[u] = 1;
  for(int i = head[u]; ~i; i=edge[i].next) {
    v = edge[i].v;
    if(!dfn[v]) {
      tarjan(v);
      low[u] = min(low[u], low[v]);
    }
    else if(instk[v]) low[u] = min(low[u], dfn[v]);
  }
  if(dfn[u] == low[u]) {
    bcnt++;
    do {
      v = stk[top--];
      instk[v] = 0;
      belong[v] = bcnt;
    } while(v != u);
  }
}

int main() {
  // freopen("in", "r", stdin);
  // freopen("out", "w", stdout);

  int uu, vv;
  while(~scanf("%d %d", &n, &m)) {
    init();
    for (int i = 1; i <= m; i++) {
      scanf("%d %d", &uu, &vv);
      if (uu == vv) continue;
      adde(uu, vv);
    }
    for(uu = 1; uu <= n; uu++) {
      if(!dfn[uu]) {
        tarjan(uu);
      }
    }
    for(int i = 0; i < ecnt; i++) {
      if(belong[edge[i].u] != belong[edge[i].v]) {
        in[belong[edge[i].u]]++;
        out[belong[edge[i].v]]++;
      }
    }
    unordered_map<int, int> vis;
    for (int i = 1; i <= n; i++) {
      vis[belong[i]]++;
    }
    LL ret = 0;
    for (const auto x : vis) {
      LL cnt = x.second;
      ret += (cnt - 1) * cnt / 2;
    }
    printf("%lld\n", ret);
  }
  return 0;
}




#网易##笔试题目##笔经#
全部评论
楼主牛批,第二题看了你的发现可以直接一维dp,代表前i个人最少购票时间,只有我这么菜的笔试的时候才会去暴力解了😭 void formatTime(int sec) { int h = 0, m = 0, s = 0; s = sec; h = s / 3600; m = (s - h * 3600) / 60; s = s - h * 3600 - m * 60; h += 8; string suf = (h <= 12 ? "am" : "pm"); printf("%02d:%02d:%02d %s\n", h, m, s, suf.c_str()); } int main() { int T = 0; cin >> T; while (T--) { int n = 0; cin >> n; vector<int> a(n + 1, 0); vector<int> b(n + 1, 0); vector<int> dp(n + 1, 0); for (int i = 1; i <= n; i++) cin >> a[i]; for (int i = 2; i <= n; i++) cin >> b[i]; dp[0] = 0; dp[1] = a[1]; for (int i = 2; i <= n; i++) { dp[i] = min(dp[i - 1] + a[i], dp[i - 2] + b[i]); } formatTime(dp[n]); } }
1 回复
分享
发布于 2020-08-09 14:13
抢个位置。网格世界这题有啥思路吗
点赞 回复
分享
发布于 2020-08-08 16:08
百信银行
校招火热招聘中
官网直投
大佬给个解答?
点赞 回复
分享
发布于 2020-08-08 16:09
哭了 第三题居然可以暴力过🤣
点赞 回复
分享
发布于 2020-08-08 16:52
。。。第二题下午的时间hour没减12,卡65%了,哭了
点赞 回复
分享
发布于 2020-08-08 16:56
大佬, 第二题能提供几个测试样例吗 为啥我是0%啊啊啊啊啊啊
点赞 回复
分享
发布于 2020-08-08 16:57
第四题,我也求的强连通分量,然后统计个数,为何只过了10%,是哪里有坑吗,我也去重了呀
点赞 回复
分享
发布于 2020-08-08 17:41
点赞 回复
分享
发布于 2020-08-08 23:59

相关推荐

10 28 评论
分享
牛客网
牛客企业服务