zoukankan      html  css  js  c++  java
  • 探索数字迷塔问题及遇到指针无法访问内存的错误

    Problem : 探索数字迷塔

    Time Limit: 1 Sec  Memory Limit: 64 MB

    Description

    晶晶最近迷上了数字迷宫游戏,整天沉浸在一串串看似简单的数字中自得其乐。数字迷宫游戏的魅力体现在变化中隐含着不变的规律,归纳是探究数字迷宫的法宝之一。图10.1-1就是一个由线连接起来的数字小方格组成的数字迷塔。

    这个迷塔共n层,它由n×(n+1)/2个小方格组成。每个小方格中都有一个数字,并且连着下一层的两个小方格。现从塔顶走到塔底,每一步只能走到相邻的方格中,则经过方格的数字之和最大值是多少?这个问题晶晶已经琢磨一天了,她感觉异常棘手。你能帮帮她吗?

    Input

    输入数据共n+1行,第1行是一个整数n(1≤n≤1000),表示数字迷塔的高度,接下来用n行数字表示数字迷塔,其中第i行有i个正整数,且所有的正整数均不大于100。

    Output

    输出可能得到的最大和。

    Sample Input

    5

    9

    12 15

    10 6 8

    2 18 9 5

    19 7 10 4 16

    Sample Output

    59

    HINT

    样例说明:9→12→10→18→10

     

    方法策略

      对于这个问题,首先我想到的是从特殊到一般的方法,即先考虑一个较少的输入范围,如输入高度为5,然后思考如何用实际方法解决这个问题,再得出一般性的结论。先来分析这个特殊的树,它是有向的图,每个节点(除叶子外)都有两个子节点,而且相邻两个节点还共有一个子节点。很容易把它想象一个楼梯的模型,那么父节点与子结点的位置关系就很清楚了,即子节点在父节点的正下方和右下角,所以遍历这棵树和建立树的结构就迎刃而解了。对于求最大消耗路径问题,考虑到父子节点间的关系,可以采用用动态规划的方法解决,即:

    cost(总)= cost(父) +  MAX(cost(子左),cost(子右))

    找到了递推关系,应该很容易计算出结果了。

      具体如何建立这棵树呢?首先,还是用老办法,定义一个结构来表示每个节点(含数据,左、右指针等成员)。然后考虑如何输入数据和初始化所有节点:首先定义一个方法,输入是树的高度,输出是根节点的地址(便于访问树);利用树的高度信息及确定每层所含节点的数目,所以可以直接用动态数组来生成每层的节点,但是同时还要保留该数组的首地址,便于下面访问节点,所以需要创建一个二级指针来记录; 最后用两层循环来让父结点的指针指向子节点即可。

     

    相应代码:

     1 /*
     2  *  numberati.cpp
     3  *  Copyright 2015 Kevin <Kevin@YU_WINDOWS8>
     4  *  
     5  *  This program is intented to solve the Digit Magic Tower problem.
     6  *
     7  */
     8 
     9 #include<iostream>
    10 using namespace std;
    11 
    12 /* Definiton of Node with the struct type*/
    13 struct Node{
    14     int data;
    15     Node * left;
    16     Node * right;      
    17 };
    18 
    19 /* Function Declaration */
    20 Node * buildTree();
    21 int findMaxPath(Node * root);
    22 int max(int, int);
    23 
    24 /* Drive for */
    25 int main(){
    26     Node * root = buildTree();
    27     cout << findMaxPath(root);
    28     return 0;
    29 }
    30 
    31 /* Utility function to build a tree */
    32 Node * buildTree(){
    33     int height=1;
    34     cin >> height;
    35 
    36     // Make space to hold the value
    37     Node ** temp=new Node *[height];
    38     for (int i = 0; i < height; i++){
    39         temp[i] = new Node[i + 1];         // for every column, use a pointer to access the elements
    40         for (int j = 0; j <= i; j++){
    41             cin >> temp[i][j].data;
    42             temp[i][j].left = NULL;
    43             temp[i][j].right = NULL;        // Intilize the pointers 
    44         }        
    45     }
    46         
    47     // To link the elements, make pointers point their children
    48     for (int i = 0; i<height-1; i++){
    49         for (int j = 0; j <= i; j++){
    50             temp[i][j].left = &temp[i + 1][j];
    51             temp[i][j].right = &temp[i + 1][j + 1];
    52         }
    53     }
    54 
    55     return temp[0];                        // return the root node's adress
    56 }
    57 
    58 /* Utility function to find the max path, and return the final cost */
    59 int findMaxPath(Node * root){
    60     if (root==NULL)               // Intilize the pointer before using it.
    61         return 0;
    62         
    63     int Max = max(findMaxPath(root->left), findMaxPath(root->right));
    64     return (root->data + Max);        
    65 }
    66 
    67 /* Get the larger value from two inputs */
    68 int max(int a, int b){
    69     if (a<b)
    70         return b;
    71     else
    72         return a;
    73 }
    View Code

    编写代码中出现的问题:

      由于之前很久没有用c++,就把c++中一些基本而重要的概念忘记了。例如,在创建一个变量的时候,一定要适当地将它初始化,否则很容易出现运行时错误。特别是指针,由于它直接访问内存,若没有很好的处理,很容易就早成程序意外地终止。在编写这个程序中,我就不幸遇到这个问题,由于没有初始化节点的左右指针,出现了无法读取内存的运行时错误,导致自己调试了很久都没明白错误的来源(ps,也可能自己水平还不够吧)。因为个人觉得这个教训比较重要,在此记录该错误,希望以后能引以为鉴。

    用VS2013调试:      

    注释掉初始化子节点的左右指针:

    测试代码:

    程序能启动运行

    输入数据后运行中断:

    调试代码发现:

    当访问到叶子节点的指针时出现了错误,data=???,left=???,right=???

    最后,去掉注释后,在dos窗口下用g++编译能正常运行:

    • OJ

      推荐一个在线OJ的网站(OJ是Online Judge系统的简称,用来在线检测程序源代码的正确性)

      https://leetcode.com/ 

    分享请注明来源:http://www.cnblogs.com/7explore-share 请尊重别人的创作,谢谢!
  • 相关阅读:
    AIX 常用命令
    local_listener 与 remote_listener 参数说明
    IBM AIX 5.3 系统管理 系统启动过程详解
    exp/imp 与 expdp/impdp 对比 及使用中的一些优化事项
    local_listener 与 remote_listener 参数说明
    SSH 连接慢 与 反向解析
    Configuring raw devices (multipath) for Oracle Clusterware 10g Release 2 (10.2.0) on RHEL5OEL5 [ID 564580.1]
    Parameter DIRECT: Conventional Path Export Versus Direct Path Export [ID 155477.1]
    AIX 系统介绍
    Oracle 数据文件(Datafile ) 大小 限制 说明
  • 原文地址:https://www.cnblogs.com/7explore-share/p/4525562.html
Copyright © 2011-2022 走看看