微软 2017春招真题

题目

There is a tree of N nodes which are numbered from 1 to N. Unfortunately, its edges are missing so we don't know how the nodes are connected. Instead we know:

  1. Which nodes are leaves
  2. The distance (number of edges) between any pair of leaves
  3. The depth of every node (the root's depth is 1)
  4. For the nodes on the same level, their order from left to right

Can you restore the tree's edges with these information? Note if node u is on the left of node v, u's parent should not be on the right of v's parent.



输入

The first line contains three integers N, M and K. N is the number of nodes. M is the depth of the tree. K is the number of leaves.

The second line contains M integers A1, A2, ... AM. Ai represents the number of nodes of depth i.

Then M lines follow. The ith of the M lines contains Ai numbers which are the nodes of depth i from left to right.  

The (M+3)-th line contains K numbers L1, L2, ... LK, indicating the leaves.

Then a K × K matrix D follows. Dij represents the distance between Li and Lj.1 ≤ N ≤ 100

输出

For every node from 1 to N

 output its parent. Output 0 for the root's parent.

样例输入

8 3 5

1 3 4

1

2 3 4

5 6 7 8

3 5 6 7 8

0 3 3 3 3

3 0 2 4 4

3 2 0 4 4

3 4 4 0 2

3 4 4 2 0

样例输出

0 1 1 1 2 2 4 4

分析

首先,给出的测试用例太过简单,先构建一个复杂的测试用例:



从下往上,从左往右遍历:

第六层(最下层):

第一个节点26,其父节点一定是第五层第一个非叶子节点20。同时,在距离矩阵中增加节点20,与其他节点距离为节点26与其他节点距离-1

第二个节点27,若和26的距离为2,则其父节点也是20(×),否则,其父节点是第五层第二个非叶子节点22(√)同时,在距离矩阵中增加节点22,与其他节点距离为节点27与其他节点距离-1

第三个节点28,若和27的距离为2,则其父节点也是22(√),否则,其父节点是第五层第三个非叶子节点24(×)

......

第六层遍历结束,明确了第六层所有节点的父节点,也将第五层所有非叶子节点加入距离矩阵



第五层(倒数第二层):

第一个节点19,其父节点一定是第四层第一个非叶子节点13。同时,在距离矩阵中增加节点13,与其他节点距离为节点19与其他节点距离-1

第二个节点20,若和19的距离为2,则其父节点也是13(√),否则,其父节点是第四层第二个非叶子节点14(×)

......

第五层遍历结束,明确了第五层所有节点的父节点,也将第五层所有非叶子节点加入距离矩阵

......



(一直遍历到第三层)

第二层:

所有节点的父节点都是根节点(第一层的唯一节点)

第一层:

根节点的父节点为0

解答

解法1:结果是Wrong Answer,然而并不知道为什么,谁能帮我看看错在哪了哇~

    import java.util.Scanner;
import java.util.Map;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.concurrent.ConcurrentHashMap; public class Main_2 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();//节点数8
int m = sc.nextInt();//树深度3
int k = sc.nextInt();//叶子树5
int[] a = new int[m];//深度为i的节点数
int[][] arr = new int[m][];//每行的节点data
Node[][] nodes = new Node[m][];//每行的节点
Map<Integer, Node> nodesMap = new LinkedHashMap<>();//存节点
Map<Node, Map<Node,Integer>> distanceMap = new ConcurrentHashMap<>();//存节点间距离(叶子+非叶子) for (int i = 0; i < m; i++) {
a[i] = sc.nextInt();
arr[i] = new int[a[i]];
nodes[i] = new Node[a[i]];
} for (int i = 0; i < m; i++) {
for (int j = 0; j < a[i]; j++){
arr[i][j] = sc.nextInt();
nodes[i][j] = new Node();
nodes[i][j].data = arr[i][j];
nodes[i][j].level = i + 1;
nodesMap.put(arr[i][j],nodes[i][j]); if(i == 0){
nodes[i][j].parent = null;
}
else if(i == 1){
nodes[i][j].parent = nodes[0][0];
}
}
}
int[] l = new int[n];//叶子 3 5 6 7 8
for(int i = 0; i < k; i++){
l[i] = sc.nextInt();
nodesMap.get(l[i]).isLeaf = true;
} int[][] d = new int[n][n];//叶子节点间距离 for (int i = 0; i < k; i++) {
Map<Node, Integer> tempMap = new ConcurrentHashMap<>();
for (int j = 0; j < k; j++){
d[i][j] = sc.nextInt();
if (l[i] < l[j]){
tempMap.put(nodesMap.get(l[j]),d[i][j]);
distanceMap.put(nodesMap.get(l[i]),tempMap);
}
}
}
//从下往上,从左往右遍历
for(int i = m - 1; i >= 2; i--){
int ii = i - 1;//上一层
int jj = 0;//上一层第0个节点
Node lastNode = null;
for(int j = 0; j < a[i]; j++){
if (lastNode != null){//不是本层第一个节点,计算该节点与本层上一个节点的距离
int distance = (distanceMap.get(lastNode) != null && distanceMap.get(lastNode).get(nodes[i][j]) != null) ? distanceMap.get(lastNode).get(nodes[i][j]) : distanceMap.get(nodes[i][j]).get(lastNode);
if (distance == 2){
nodes[i][j].parent = lastNode.parent;
continue;
}
} while (nodes[ii][jj].isLeaf){
jj++;
} nodes[i][j].parent = nodes[ii][jj];
//在距离矩阵中增加其父节点
Iterator it1 = distanceMap.entrySet().iterator(); while (it1.hasNext()) {
Map.Entry outerEntry = (Map.Entry) it1.next();
Node outerKey = (Node) outerEntry.getKey();
Map<Node,Integer> outerValue = (Map<Node,Integer>) outerEntry.getValue(); if(outerKey == nodes[i][j]){
Map<Node, Integer> tempMap = new ConcurrentHashMap<>();
Iterator it2 = outerValue.entrySet().iterator();
while (it2.hasNext()) {
Map.Entry entry = (Map.Entry) it2.next();
Node innerKey = (Node) entry.getKey();
Integer innerValue = (Integer) entry.getValue();
tempMap.put(innerKey,innerValue - 1);
}
distanceMap.put(nodes[i][j].parent,tempMap);
} else{
Iterator it2 = outerValue.entrySet().iterator();
while (it2.hasNext()) {
Map.Entry entry = (Map.Entry) it2.next();
Node innerKey = (Node) entry.getKey();
Integer innerValue = (Integer) entry.getValue(); if(innerKey == nodes[i][j]){
Map<Node, Integer> tempMap = distanceMap.get(outerKey);
tempMap.put(nodes[i][j].parent,innerValue - 1);
distanceMap.put(outerKey,tempMap);
}
}
} }
lastNode = nodes[i][j];
jj++;
}
}
for (Map.Entry<Integer, Node> entry : nodesMap.entrySet()) {
Node thisNode = entry.getValue();
int result = (thisNode.parent != null) ? thisNode.parent.data : 0;
System.out.print(result+" ");
}
}
}
class Node{
public Node parent;
public int data;
public int level;
public boolean isLeaf;
}

附两个测试用例:

9 4 6

1 2 3 4

9

1 10

2 3 4

5 6 7 8

3 5 6 7 8 10

0 3 3 3 3 3

3 0 2 4 4 4

3 2 0 4 4 4

3 4 4 0 2 4

3 4 4 2 0 4

3 4 4 4 4 0


31 6 13
1 4 6 7 7 6
1
2 3 4 5
6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
3 8 12 15 19 21 23 26 27 28 29 30 31
0 3 4 4 5 5 5 6 6 6 6 6 6
3 0 3 5 4 4 6 5 7 7 7 7 7
4 3 0 6 5 5 7 6 8 8 8 8 8
4 5 6 0 7 7 7 8 4 4 8 8 8
5 4 5 7 0 4 8 3 9 9 9 9 9
5 4 5 7 4 0 8 5 9 9 9 9 9
5 6 7 7 8 8 0 9 9 9 7 7 7
6 5 6 8 3 5 9 0 10 10 10 10 10
6 7 8 4 9 9 9 10 0 2 10 10 10
6 7 8 4 9 9 9 10 2 0 10 10 10
6 7 8 8 9 9 7 10 10 10 0 2 4
6 7 8 8 9 9 7 10 10 10 2 0 4
6 7 8 8 9 9 7 10 10 10 4 4 0

#1490 : Tree Restoration的更多相关文章

  1. hihocoder 1490 Tree Restoration

    构造. 从最后一层开始往上构造.最后一层肯定都是叶子结点,距离为2的肯定是同一个父亲,确定好了父亲之后,可以确定上一层每个节点之间的距离,以及上一层每个节点到还未确定的叶子节点之间的距离. #incl ...

  2. Tree Restoration Gym - 101755F (并查集)

    There is a tree of n vertices. For each vertex a list of all its successors is known (not only direc ...

  3. hihocoder1490 Tree Restoration 模拟

    There is a tree of N nodes which are numbered from 1 to N. Unfortunately, its edges are missing so w ...

  4. 【微软2017年预科生计划在线编程笔试 B】Tree Restoration

    [题目链接]:https://hihocoder.com/problemset/problem/1490 [题意] 给你一棵树的以下信息: 1.节点个数 2.给出树的每一层从左到右的顺序每个节点的编号 ...

  5. #1490 : Tree Restoration-(微软2017在线笔试)

    输入n m km个数,表示每层的节点个数接下来m行是每层的节点,节点顺序是从左往右的k个叶子节点k*k个矩阵,表示叶子节点之间的距离 输出:每个节点的父亲节点编号,root节点是0 题解:1.很明显, ...

  6. Codeforces gym101755F Tree Restoration(拓扑排序)

    题意: 一棵树,给出每个点的后代们,问你这棵树是否存在,存在就给出这棵树 n<=1000 思路: 对祖先->后代建立有向图,跑拓扑排序.跑的时候不断更新父亲并判断答案的存在性,同时注意一种 ...

  7. Codeforces Round #504 D. Array Restoration

    Codeforces Round #504 D. Array Restoration 题目描述:有一个长度为\(n\)的序列\(a\),有\(q\)次操作,第\(i\)次选择一个区间,将区间里的数全部 ...

  8. iOS Programming State Restoration 状态存储

    iOS Programming State Restoration 状态存储 If iOS ever needs more memory and your application is in the ...

  9. [数据结构]——二叉树(Binary Tree)、二叉搜索树(Binary Search Tree)及其衍生算法

    二叉树(Binary Tree)是最简单的树形数据结构,然而却十分精妙.其衍生出各种算法,以致于占据了数据结构的半壁江山.STL中大名顶顶的关联容器--集合(set).映射(map)便是使用二叉树实现 ...

随机推荐

  1. SEO优化上首页之搜索引擎原理内容处理与索引

    上文<搜索引擎原理SEO优化上首页之蜘蛛Spider>详细介绍了蜘蛛的分类.抓取入口.抓取策略和更新策略.搜索引擎已把页面抓取回来,接下来是解析页面内容,主要包含判断页面类型.提取页面主题 ...

  2. 2017-2018-1 20155231 《信息安全系统设计基础》实现mypwd

    2017-2018-1 20155231 <信息安全系统设计基础>实现mypwd Linux pwd命令用于显示工作目录. 执行pwd指令可立刻得知您目前所在的工作目录的绝对路径名称. p ...

  3. 19-[模块]-json/pickle、shelve

    1.序列化? 序列化是指把内存里的数据类型转变成字符串,以使其能存储到硬盘或通过网络传输到远程,因为硬盘或网络传输时只能接受bytes (1)把字典保存到文件 data = { 'roles': [ ...

  4. 25-[jQuery]-事件

    重点:jQuery事件绑定on().bind()与delegate() 方法详解 1.jquery的事件 <!DOCTYPE html> <html lang="en&qu ...

  5. Scikit-Learn机器学习入门

    现在最常用的数据分析的编程语言为R和Python.每种语言都有自己的特点,Python因为Scikit-Learn库赢得了优势.Scikit-Learn有完整的文档,并实现很多机器学习算法,而每种算法 ...

  6. mongodb原生node驱动

    写在前面 最近读<node.js学习指南>,对于mongodb没有介绍太多的工作原理,但是对于一个前端开发者,即使你还没有用过这种数据库也可以让你很好的理解和使用       一本非常好的 ...

  7. css清除浮动clearfix:after的用法详解

    如果外部有一个div容器,其内部div容器设置了float样式,则外部的容器div因为内部没有clear,导致不能撑开.解决方法:  CSS代码: 复制代码 代码如下: .clearfix:after ...

  8. linux分区满了,如何进行扩容

    转自:https://blog.csdn.net/valage/article/details/73332147 图片中可以看到挂载点“/”的利用率移到100%,空间不够,所以要对其进行分区. 1.  ...

  9. java练习(一)数组、集合的运用

    有这么一个有趣的问题,问:有这么一个不重复的自然数数组,自然数长度为N,而数组长度为N-2,依次随机把自然数放进数组中,请找出2个没有被放进去的自然数.例如:这个自然数数组是[0, 1, 2, 3,  ...

  10. [C++]linux下实现rm()函数删除文件或目录

    转载请注明原创:http://www.cnblogs.com/StartoverX/p/4600866.html 在linux下有两个函数可以用来删除文件: #include <unistd.h ...