zoukankan      html  css  js  c++  java
  • 算法练习(六)

    一、二叉树的遍历-1

    题目

    输入图片说明

    写出这个二叉树的前序遍历,中序遍历,后序遍历。

    答案

    前序遍历,也叫先根遍历,遍历的顺序是,根,左子树,右子树

    遍历结果:A,B,E,F,C,G

    中序遍历,也叫中根遍历,顺序是 左子树,根,右子树

    遍历结果:E,B,F,A,G,C

    后序遍历,也叫后根遍历,遍历顺序,左子树,右子树,根

    遍历结果:E,F,B,G,C,A

    代码

    #include<stdio.h>
    #include<stdlib.h>
    
    typedef struct BiTNode {
    	char data;
    	struct BiTNode *lc, * rc;
    }BiTNode, *BiTree;
    
    BiTree createBT() {
    	BiTree t;
    	char c;
    	scanf("%c",&c);
    	
    	if (c == '#') // # 代表null
    		t = NULL;
    	else {
    		t = (BiTree)malloc(sizeof(BiTNode));
    		t -> data = c;
    		t -> lc = createBT();
    		t -> rc = createBT();
    	} 
    	
    	return t;
    }
    
    void PreOrderTraverse(BiTree t) { // 前序遍历 
    	if (t == NULL)
    		return;
    	printf("%c",t -> data);
    	PreOrderTraverse(t -> lc);
    	PreOrderTraverse(t -> rc);
    }
    
    void InOrderTraverse(BiTree t) { // 中序遍历 
    	if (t == NULL)
    		return;
    	InOrderTraverse(t -> lc);
    	printf("%c",t -> data);
    	InOrderTraverse(t -> rc);
    }
    
    void PosOrderTraverse(BiTree t) { // 后序遍历 
    	if (t == NULL)
    		return;
    	PosOrderTraverse(t -> lc);
    	PosOrderTraverse(t -> rc);
    	printf("%c",t -> data);
    }
    
    int main() {
    	BiTree t;
    	
    	t = createBT();
    	printf("前序遍历:");
    	PreOrderTraverse(t);
    	printf("
    中序遍历:");
    	InOrderTraverse(t);
    	printf("
    后序遍历:");
    	PosOrderTraverse(t);
    	
    	return 0;
    }
    
    //ABE##F##CG###
    

    解题思路

    运用二叉树的构建及递归的思想完成此题,要注意三种遍历方式的不同。


    二、二叉树的遍历-2

    题目

    依次给出二叉树的前序历遍和中序历遍,请输出它的后序历遍

    Input

    输入包含多个测试用例。每个测试用例的第一行包含一个整数n(1 < = n < = 1000),二叉树的结点的个数。其次是两行,分别表示前序遍历和中序遍历。

    Output

    为每个测试用例输出一行指定相应的后序遍历结果。

    Sample Input

    9

    1 2 4 7 3 5 8 9 6

    4 7 2 1 8 5 9 3 6

    Sample Output

    7 4 2 8 9 5 6 3 1

    请思考:

    如果给出中序遍历和后序遍历能否求出前序遍历呢?

    如果给出前序遍历和后序遍历能否求出中序遍历呢?

    代码

    #include<stdio.h>
    int t1[1000],t2[1000];
    
    void pos(int a,int b,int n) { // a为前序的位置,b为中序的位置,n为结点数
    	if (n == 1) { // 结点数为 1,此时为叶结点 
    		printf("%d ",t1[a]);
    		return;
    	} else if (n < 1) {
    		return;
    	}
    	
    	int i;
    	for (i = 0; t1[a] != t2[b+i]; i++);
    	
    	pos(a+1,b,i); // 左树 
    	pos(a+i+1,b+i+1,n-i-1); // 右树
    	
    	// 输出结点(根结点或内部结点) 
    	printf("%d ",t1[a]);
    }
    
    int main() {
    	int n,j;
    	while (scanf("%d",&n) != EOF) {
    		for (j = 0; j < n; j++) 
    			scanf("%d",&t1[j]);
    		for (j = 0; j < n; j++) 
    			scanf("%d",&t2[j]);
    			
    		pos(0,0,n);
    		printf("
    ");
    	}
    	
    	return 0;
    }
    

    解题思路

    利用递归思想,不断区分左树与右树,当只有一个节点时输出该结点。

    思考:给出中序遍历和后序遍历可以求出前序遍历;给出前序遍历和后序遍历不能求出中序遍历


    三、回家过年

    题目

    NowCoder今年买了一辆新车,他决定自己开车回家过年。回家过程中要经过n个大小收费站,每个收费站的费用不同,你能帮他计算一下最少需要给多少过路费吗?

    输入描述:

    输入包含多组数据,每组数据第一行包含两个正整数m(1≤m≤500)和n(1≤n≤30),其中n表示有n个收费站,编号依次为1、2、…、n。出发地的编号为0,终点的编号为n,即需要从0到n。
    紧接着m行,每行包含三个整数f、t、c,(0≤f, t≤n; 1≤c≤10),分别表示从编号为f的地方开到t,需要交c元的过路费。

    输出描述:

    对应每组数据,请输出至少需要交多少过路费。

    示例

    输入:
    8 4
    0 1 10
    0 2 5
    1 2 2
    1 3 1
    2 1 3
    2 3 9
    2 4 2
    3 4 4
    输出:
    7
    

    地址

    代码

    #include<stdio.h>
    
    int main() {
    	int m,n;
    	while (scanf("%d %d",&m,&n) != EOF) {
    		int i,j,k,x,y;
    		int a[n+1][n+1];
    		for (i = 0; i <= n; i++) 
    			for (j = 0; j <= n; j++) 
    				a[i][j] = 99; // 初始化二维数组为一个较大值 
    		for (i = 0; i < m; i++) {
    			scanf("%d%d",&x,&y);
    			scanf("%d",&a[x][y]);
    		}
    		for (k = 0; k <= n; k++)
    			for (i = 0; i <= n; i++) 
    				for (j = 0; j <= n; j++) {
    					a[i][j] = a[i][j] < (a[i][k] + a[k][j])?a[i][j]:(a[i][k] + a[k][j]);
     				}
     		printf("%d
    ",a[0][n]);
    	}
    	return 0;
    }
    

    解题思路

    floyd算法,演示所有过程,求最小值。


    四、走迷宫

    题目

    NowCoder最喜欢游乐场的迷宫游戏,他和小伙伴们比赛谁先走出迷宫。
    现在把迷宫的地图给你,你能帮他算出最快走出迷宫需要多少步吗?

    输入描述:

    输入包含多组数据。

    每组数据包含一个10*10,由“#”和“.”组成的迷宫。其中“#”代表墙;“.”代表通路。入口在第一行第二列;出口在最后一行第九列。从任意一个“.”点都能一步走到上下左右四个方向的“.”点。

    输出描述:

    对应每组数据,输出从入口到出口最短需要几步。

    示例

    输入图片说明

    地址

    代码

    #include<stdio.h> 
    struct note{
    	int x;
    	int y;
    	int s;
    };
    
    int main() {
    	struct note queue[1001];
    	char a[11][12],book[11][12];
    	int next[4][2] = {{1,0},{0,1},{-1,0},{0,-1}};
    	
    	int i,j;
    	while (scanf("%c",&a[1][1]) != EOF) {
    		for (i = 2; i <= 11; i++) {
    			scanf("%c",&a[1][i]);
    		}
    		for (i = 2; i <= 10; i++) {
    			for (j = 1; j <= 11; j++) { // 注意此处 j 的范围 
    				scanf("%c",&a[i][j]);
    				book[i][j] = '.';
    			}
    		}
    		// 上面的内容为输入地图数据 
    		
    		int head = 1;
    		int end = 1;
    		queue[end].x = 1;
    		queue[end].y = 2;
    		queue[end].s = 0;
    		end++;
    		
    		book[1][2] = '#';
    		
    		while (head < end) {
    			for (i = 0; i < 4; i++) {
    				int tx = queue[head].x + next[i][0];
    				int ty = queue[head].y + next[i][1];
    				if (tx < 1 || tx > 10 || ty < 1 || ty >10) {
    					continue;
    				}
    					
    				if (a[tx][ty] == '.' && book[tx][ty] == '.') {
    					book [tx][ty] = '#';
    					queue[end].x = tx;
    					queue[end].y = ty;
    					queue[end].s = queue[head].s + 1;
    					end++;
    				}
    				
    				if (tx == 10 && ty == 9) 
    					goto end;
    			}
    			head++;
    		}
    		end:
    			printf("%d
    ",queue[end - 1].s);
    	} 
    	return 0;
    }
    

    解题思路

    bfs思想,用队列就可以。

    注意:此题的地图为字符型构建,不同于整型,回车符也会被记录,所以要扩大数组范围。

    附:人生目标

    那个看我这周写这么多,以前的一笔勾销好不好,啦啦啦!

    以上

  • 相关阅读:
    HDU 1394 Minimum Inversion Number
    LA 3938 动态最大连续和(线段树)
    HDU 1754 I Hate It(线段树)
    HDU 1166 敌兵布阵(线段树 or 二叉索引树)
    《乞力马扎罗的雪》读书笔记
    LA 3266 田忌赛马
    UVa 11235 频繁出现的数值
    《月亮与六便士》读书笔记
    LA 3135 阿格斯(优先队列)
    LA 3027 合作网络
  • 原文地址:https://www.cnblogs.com/mxwbq/p/7353881.html
Copyright © 2011-2022 走看看