华为9.9笔试 第二题第三题题解

第二题
将每个方格视为一个点 若两个相邻点满足一个点的值小于另外一个点 就连一条有向边 显然这个图肯定是个DAG(有向无环图) 在DAG跑一遍最长路dp就可以了 复杂度((4*n*n+n*n))
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <unordered_map>
#include <vector>
#define fir first
#define se second
#define ll long long
#define pb push_back
#define mp make_pair
#define ull unsigned long long
#define cl(a, b) memset(a, b, sizeof(a))
#define quickio(a) ios::sync_with_stdio(a)
#define datatest() freopen("data.in", "r", stdin)
#define makeans() freopen("data.out", "w", stdout)
#define makedata() freopen("data.in", "w", stdout)
#define pii pair<int, int>
#define pll pair<ll, ll>
#define pdd pair<double, double>
using namespace std;
const int maxn = 1000 + 10;
const int maxm = 1e6 + 10;
const int inf = 0x3f3f3f3f;
const ll mod = 1e9 + 7;
const int maxblock = sqrt(maxn) + 10;
const double eps = 1e-7;
const ll INF = 1e16;
struct Edge {
  int u, v, next;
} edge[maxn * maxn * 4];
int head[maxn * maxn];
int tot = 0;
int in[maxn * maxn];
void init() {
  cl(head, -1);
  cl(in, 0);
  tot = 0;
}
void addedge(int u, int v) {
  edge[tot] = Edge{u, v, head[u]};
  head[u] = tot++;
  in[v]++;
}
int n, m;
int a[maxn][maxn];
int id[maxn][maxn];
int dx[4] = {-1, 1, 0, 0};
int dy[4] = {0, 0, -1, 1};
int legal(int x, int y) { return (x >= 1 && x <= n && y >= 1 && y <= m); }
int dp[maxn * maxn];
int main() {
  scanf("%d %d", &n, &m);
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= m; j++) scanf("%d", &a[i][j]);
  }
  int now_id = 0;
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= m; j++) id[i][j] = ++now_id;
  }
  init();
  for (int x = 1; x <= n; x++) {
    for (int y = 1; y <= m; y++) {
      for (int i = 0; i < 4; i++) {
        int xx = x + dx[i];
        int yy = y + dy[i];
        if (legal(xx, yy) && a[x][y] < a[xx][yy]) {
          addedge(id[x][y], id[xx][yy]);
        }
      }
    }
  }
  std::queue<int> q;
  cl(dp, 0);
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= m; j++) {
      if (!in[id[i][j]]) {
        q.push(id[i][j]);
        dp[id[i][j]] = 1;
      }
    }
  }
  int Max = 0;
  while (!q.empty()) {
    int u = q.front();
    q.pop();
    Max = std::max(Max, dp[u]);
    for (int i = head[u]; ~i; i = edge[i].next) {
      int v = edge[i].v;
      dp[v] = std::max(dp[v], dp[u] + 1);
      in[v]--;
      if (!in[v]) {
        q.push(v);
      }
    }
  }
  printf("%d\n", Max);
  return 0;
}
第三题
假设根为root,令从root到i节点路径的异或为sum[i],那么路径(u,v)的异或值就是sum[u]^sum[v]
于是,可以从根节点dfs,并快速查询满足sum[u]^sum[v]的最大的v即可
查询可以采用01字典树完成
复杂度((n+e)*30)
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <unordered_map>
#include <vector>
#define fir first
#define se second
#define ll long long
#define pb push_back
#define mp make_pair
#define ull unsigned long long
#define cl(a, b) memset(a, b, sizeof(a))
#define quickio(a) ios::sync_with_stdio(a)
#define datatest() freopen("data.in", "r", stdin)
#define makeans() freopen("data.out", "w", stdout)
#define makedata() freopen("data.in", "w", stdout)
#define pii pair<int, int>
#define pll pair<ll, ll>
#define pdd pair<double, double>
using namespace std;
const int maxn = 1e5 + 10;
const int maxm = 1e6 + 10;
const int inf = 0x3f3f3f3f;
const ll mod = 1e9 + 7;
const int maxblock = sqrt(maxn) + 10;
const double eps = 1e-7;
const ll INF = 1e16;
const int N = 1e5 * 30 + 10;
struct Trie {
  using LL = long long;
  LL ch[N][2], sz;
  LL val[N], ed[N];
  void Init() {
    memset(ch[0], 0, sizeof(ch[0]));
    ed[0] = 0;
    sz = 1;
  }
  void Insert(LL x) {
    int u = 0;
    for (int i = 40; i >= 0; i--) {
      int v = (x & (1ll << i)) > 0 ? 1 : 0;
      if (!ch[u][v]) {
        memset(ch[sz], 0, sizeof(ch[sz]));
        val[sz] = 0;  //每个节点的附加信息
        ed[sz] = 0;
        ch[u][v] = sz++;  //存储该节点的编号sz
      }
      u = ch[u][v];
      val[u]++;
    }
    ed[u] = x;  //最后一个节点记录数值
  }
  void Delete(LL x) {
    int u = 0;
    for (int i = 40; i >= 0; i--) {
      int v = (x & (1ll << i)) > 0 ? 1 : 0;
      u = ch[u][v];
      val[u]--;
    }
    // ed[u]=0;//可能有重复数字,若置为0后该位置的另一个数字也被删除了
  }
  LL Search(LL x) {
    int u = 0;
    for (int i = 40; i >= 0; i--) {
      int v = (x & (1ll << i)) > 0;  //判断条件
      if (ch[u][!v] && val[ch[u][!v]]) {
        u = ch[u][!v];
      } else if (ch[u][v] && val[ch[u][v]]) {
        u = ch[u][v];
      } else
        return x ^ ed[u];
    }
    return x ^ ed[u];
  }
} trie;
int n;
ll w[maxn];
vector<int> g[maxn];
int in[maxn];
ll Max = 0;
ll sum[maxn];
void dfs(int u, int fa) {
  if (fa == -1) {
    sum[u] = w[u];
  } else {
    sum[u] = sum[fa] ^ w[u];
  }
  // cout << u << " " << sum[u] << endl;
  ll query = trie.Search(sum[u]);
  trie.Insert(sum[u]);
  Max = max(Max, query);
  Max = max(Max, sum[u]);
  for (int i = 0; i < g[u].size(); i++) {
    int v = g[u][i];
    if (fa == v) continue;
    dfs(v, u);
  }
  trie.Delete(sum[u]);
}
int main() {
  scanf("%d", &n);
  for (int i = 0; i <= n; i++) g[i].clear();
  cl(in, 0);
  for (int i = 1; i <= n; i++) {
    int id, l, r;
    ll weight;
    scanf("%d %lld %d %d", &id, &weight, &l, &r);
    w[id] = weight;
    if (l != -1) {
      g[id].push_back(l);
      g[l].push_back(id);
      in[l]++;
    }
    if (r != -1) {
      g[id].push_back(r);
      g[r].push_back(id);
      in[r]++;
    }
  }
  int rt = -1;
  for (int i = 1; i <= n; i++) {
    if (!in[i]) {
      rt = i;
      break;
    }
  }
  trie.Init();
  // trie.Insert(0);
  dfs(rt, -1);
  printf("%lld\n", Max);
  return 0;
}
/*
5
1 1 2 3
2 4 -1 -1
3 2 -1 4
4 5 -1 5
5 3 -1 -1
*/


#笔试题目##华为#
全部评论

相关推荐

留贴作为个人秋招记录,感谢很多前辈们的贴子,我也随一个。时间历程:7.24投递&nbsp;7.25评估&nbsp;8.9一面&nbsp;8.23二面一对一&nbsp;技术:不开摄像头&nbsp;拷打50min个人介绍,选择一个最有难度的项目,介绍你负责最有挑战性的部分是什么?项目最关键的指标有哪些?光学系统的选型,你关注什么指标?有哪些难点?相机的指标你关注那些?这款价格是多少?是否有更合适的选择?假设这款3万,给你1万的预算能否选择满足要求的相机?这个项目,如果大批量生产,你觉得要怎么改进。光学系统最后的视场有多大,你怎么保证观测的物体都能出现在视场内?设计时如何考量的?你如何保证?同类竞品,你的优势在哪里?第二个项目具体负责内容?项目需求是否正确?用户反馈的问题,测试发现没问题,站在用户角度是否合理?对于用户反馈问题测试结果正常,为什么还要改进?采集频率范围是多少?为什么采集这个范围内的?隔振率怎么计算?隔振率偏小,怎么确定静刚度过大?原理?对于一款产品,要求隔绝频率比较高的振动,橡胶该怎么选择?原理?你对于工作怎么选择你对影石公司有哪些了解你对于影石产品有什么了解,或者什么竞品你使用过,有哪些你觉得做得很好的地方和可以改进的地方。影石的两轮面试体验一直不好先不说流程推进进度缓慢,找不到联系人再说,我今天白天还显示面试中,晚上一查发现流程结束的时间,竟然是两周以前,回想起上周给hr打电话,她告诉我稍安勿躁,面试还没出结果,简直就是小丑了。#机械制造笔面经##影石Insta360求职进展汇总#
点赞 评论 收藏
分享
3 13 评论
分享
牛客网
牛客企业服务