第五章作业小结
本周老师先讲解了这道题,我觉得很不错可以分析一下,主要是还是听老师上课讲的,不像一些大佬开始用vector了...
7-2 深入虎穴 (30 分)
著名的王牌间谍 007 需要执行一次任务,获取敌方的机密情报。已知情报藏在一个地下迷宫里,迷宫只有一个入口,里面有很多条通路,每条路通向一扇门。每一扇门背后或者是一个房间,或者又有很多条路,同样是每条路通向一扇门…… 他的手里有一张表格,是其他间谍帮他收集到的情报,他们记下了每扇门的编号,以及这扇门背后的每一条通路所到达的门的编号。007 发现不存在两条路通向同一扇门。
内线告诉他,情报就藏在迷宫的最深处。但是这个迷宫太大了,他需要你的帮助 —— 请编程帮他找出距离入口最远的那扇门。
输入格式:
输入首先在一行中给出正整数 N(<),是门的数量。最后 N 行,第 i 行(1)按以下格式描述编号为 i 的那扇门背后能通向的门:
K D[1] D[2] ... D[K]
其中 K
是通道的数量,其后是每扇门的编号。
输出格式:
在一行中输出距离入口最远的那扇门的编号。题目保证这样的结果是唯一的。
输入样例:
13
3 2 3 4
2 5 6
1 7
1 8
1 9
0
2 11 10
1 13
0
0
1 12
0
0
输出样例:
12
作者: 陈越 单位: 浙江大学 时间限制: 400 ms 内存限制: 64 MB 代码长度限制: 16 KB
首先,先把main函数构建出来,那么,我们应该先读题
输入首先在一行中给出正整数 N(<),是门的数量。最后 N 行,第 i 行(1)按以下格式描述编号为 i 的那扇门背后能通向的门: K D[1] D[2] ... D[K] 其中 K 是通道的数量,其后是每扇门的编号。
那么首先是要输入一个N,代表门的数量,然后后面编号为i的门通向的门,第i行,每行有K个数;仔细分析,那么就是一棵树...而且还要把这个树存储了,输出的得是最远的那扇门。
那么就可以建立了:
int main() { node *a;//用于存储整棵树 int n, root; cin >> n; a = new node [n+1]; root = input(a , n); level(a , root); // cout << root <<endl; cout << level(a, root) <<endl; return 0; }
接着完善
建立一棵树:
typedef struct{ int doors;//[门的数量 int *p;//指向后面的门的编号序列 }node;
读入门牌号:
int input(node *a, int n) {//读入n扇门的信息给a数组,返回根所在的门牌号的下标 int i, j; bool *vi; vi = new bool[n+1]; for(i = 0; i<n+1 ; ++i)//初始化vi数组的全部元素为false { vi[i] = false; } for(i = 1; i < n+1 ;++i) {//读入n扇门的信息 cin >> a[i].doors;//对应数组的位置--直接写入 if(a[i].doors!= 0) { a[i].p = new int [a[i].doors];//申请空间 for(j = 0; j <a[i].doors ; ++j ) { cin >>a[i].p[j]; vi[a[i].p[j]] = true; }//最内部的for的结束 }//if else//doors为0的情况 a[i].p = NULL; }//外层for的结束 for( i=1; i<n+1 ; ++i ) {//找根节点所在的下标 if(!vi[i]) return i; } }
对树进行层次遍历:
int level(node *a, int r) {//从a[r]开始进行层次遍历,并返回遍历最后一个节点的编号 queue<int> q; int t,i; q.push(r); while(!q.empty()) { t = q.front(); q.pop(); if(a[t].doors!=0) {//t号门后还有门,后面的门就入队 for( i=0; i<a[t].doors ; ++i ) { q.push(a[t].p[i]); } } } return t; }
另外一道题就是画图即可解决的
Given a tree, you are supposed to list all the leaves in the order of top down, and left to right.
Input Specification:
Each input file contains one test case. For each case, the first line gives a positive integer N (≤) which is the total number of nodes in the tree -- and hence the nodes are numbered from 0 to N−1. Then N lines follow, each corresponds to a node, and gives the indices of the left and right children of the node. If the child does not exist, a "-" will be put at the position. Any pair of children are separated by a space.
Output Specification:
For each test case, print in one line all the leaves' indices in the order of top down, and left to right. There must be exactly one space between any adjacent numbers, and no extra space at the end of the line.
Sample Input:
8
1 -
- -
0 -
2 7
- -
- -
5 -
4 6
Sample Output:
4 1 5
就是根据图,来画一棵树,代码如下:
#include<iostream> #include<queue> using namespace std; //思考过程:首先是建立一个树->输入存储->然后是对其进行遍历->输出 typedef struct {//树节点的定义 --左孩子与右孩子 the definition of the tree's node int lch; int rch; }node; int createtree(node a[]) //此处要用int型的函数 { bool p[10] ={false};//此处建立一个判断函数来用于寻找根节点,也可以用负值,让数组里面所有的值为-1 int n; cin >> n;//节点的个数 char l , r ;//左右孩子 // 如果没有孩子节点,则将孩子节点的下标赋值为-1;有孩子节点,则把check[10]的孩子节点的下标改为true for(int i = 0;i < n;i++) { cin >> l >> r; if(l != '-') { a[i].lch = l-'0'; p[a[i].lch] = true; } else a[i].lch = -1; //左孩子的判断 if(r != '-') { a[i].rch = r-'0'; p[a[i].rch] = true; } else a[i].rch = -1; } //右孩子的判断 for (int i=0; i<n; i++) { if(p[i] != true) return i; //重新返回根节点 } } void levelordertree(node a[],int x) {//遍历以a[x]为根节点的树 search the tree whose root node is a[x] int t; queue<int> q; //初始化一个队列的骚操作 a initial queue q.push(x); //根结点所在下标入栈 int k ;//根据下标,来判断是否要输出空格 k = 0; while(!q.empty()) { t = q.front(); q.pop(); if(t != -1) { if(a[t].lch == -1 && a[t].rch == -1) {//输出的时候,第一个数字是不要空格的, if(k == 1) cout << " "; cout << t ; k = 1; }//if里的if q.push(a[t].lch); q.push(a[t].rch); }//while中第一个if }//while 的括号 }//遍历 int main() { node tree[10];//申请? 应该是首先创一个tree的结构体数组 int root; root = createtree(tree); levelordertree(tree, root); return 0; }