笔试题-N*N矩阵到达对角顶点寻找最大和值的路线(Qt实现)

一、题目原型:

有nn个格子,每个格子里有正数或者0,从最左上角往最右下角走,只能向下和向右,从A点走到B点,把所有经过的格子的数加起来,求最大值SUM。 (80分)
程序实现:
1)用QT、MFC或windows SDK实现对话框:首先n的输入框,输入以后点确定后,弹出 N
N矩阵的设置框。
2)计算最大的sum值。
3)显示N*N矩阵,并把最大SUM值的路过的格子,都用红色显示,不路过的白色显示。
在这里插入图片描述

二、核心算法思路

先生成n* n个随机数用于填充矩阵,存储到n* n空间大小的数组中,同时显示在界面中nn的格子中,实现一个寻路计算SUM函数,函树从n n数组左上角开始走,每次有两种情况,向下或向右,用递归执行这个过程,所有的结果最后正好可以存储在一个二叉树里面,节点记录格子坐标,和上面的所有数字和,在每条路结束后计算路径中的数值和,找出最大路径的尾节点,然后这条路径往上遍历,将其中的节点存储的方格染成红色

三、实现

1.定义存储所有路线的二叉树结构

treedata.h

#ifndef TREEDATA_H
#define TREEDATA_H

#include <QObject>


struct tree{
    QPoint p;
    int sum;
    tree *pre;
    tree *next;
    tree(int x,int y){
        p.setX(x);
        p.setY(y);
        pre=nullptr;
        next=nullptr;
        sum=0;
    }
};

class treeData
{
public:
    treeData();
    tree *getTreeD(){return treeD;}
    tree *getBest(){return best;}
    void setBest(tree *b){ best=b;}

private:
    tree *best;
    tree *treeD;
};

#endif // TREEDATA_H

treedata.cpp

#include "treedata.h"

treeData::treeData()
{

    treeD=new tree(0,0);
    best=treeD;
}

2.绘制矩阵并实现寻路算法

新建一个继承QWidget的类form

form.h

#ifndef FORM_H
#define FORM_H

#include <QWidget>
#include "treedata.h"

namespace Ui {
    class Form;
}

class Form : public QWidget
{
    Q_OBJECT

public:
    explicit Form(QWidget *parent = nullptr);
    ~Form();
    void paintEvent(QPaintEvent *event) override;
    void drawRectXY(int *N,int pos,QColor c);
    void findPath(int *N,QPoint p,tree* t); //查找最佳路径,为当前

public slots:

    void getnumber(int n);
signals:
    void showSum(int s);

private:
    Ui::Form *ui;

    int num;
    treeData *treed;
};

#endif // FORM_H

遍历所有可能路径到二叉树的函数实现:

void Form::findPath(int *N,QPoint p,tree* t) //查找最佳路径,为当前
{
    int x=p.x();
    int y=p.y();
    if(y==num)
        return;
    else if(x==num)
        x=0;
    if(t->pre!=nullptr)
        t->sum=t->pre->sum+N[y*num+x];
    if(y==x&&y==num-1&& t->sum>treed->getBest()->sum)
        treed->setBest(t);
    if(y+1<num)
    {
        t->next=new tree(x,y+1);
        t->next->pre=t;
        QPoint p(x,y+1);
        findPath(N,p,t->next);
    }
    if(x+1<num)
    {
        t->next=new tree(x+1,y);
        t->next->pre=t;
        QPoint p(x+1,y);
        findPath(N,p,t->next);
    }

}

重写该类的paintEvent(QPaintEvent *event)方法来绘制矩阵和最佳路径

void Form::paintEvent(QPaintEvent *event) {
    QPainter painter(this);
    const QRect rect = event->rect();
    QBrush brush1(qRgb(255,255, 255));
    //brush绑定到Painter 对象上
    painter.setBrush(brush1);
    //if(i==0)
    //painter.fillRect(rect,brush);
    painter.drawRect(rect);
    if(num!=0){
        int startX=10,startY=10;
        int W=this->width()-startX*2;
        int H=this->height()-startY*2;
        srand((int)time(0));  // 产生随机种子  把0换成NULL也行
        int *jz=(int*)malloc(num*num*sizeof(int));
        for(int i=0;i<=num;i++)
        {
            painter.setPen(qRgb(0, 125, 125));

            painter.drawLine(startX+i*W/num,startY,startX+i*W/num,H+startY);   //画格子
            painter.drawLine(startX,startY+i*H/num,W+startX,startY+i*H/num);



            for(int j=0;j<num&&i<num;j++)
            {
                int n=rand()%10;
                jz[num*j+i]=n;



                painter.drawText(startX+i*W/num+H/num/2,startY+j*H/num+H/num/2,QString::number(n));

            }
            //qDebug()<<endl;

        }
        QPoint p(0,0);
        //treed->
        treed->getTreeD()->sum=jz[0];
        findPath(jz,p,treed->getTreeD()); //查找最佳路径,jz矩阵,p当前遍历的点,treed存储在树的结点
        tree *tmp=treed->getBest();
        while(tmp!=nullptr)
        {
            int i=tmp->p.x(),j=tmp->p.y();
             //QRect rect(startX+i*W/num,startY+j*H/num,startX+i*W/num+W/num,startY+j*H/num+H/num);

            QBrush brush(qRgb(255, 0, 0));
            //brush绑定到Painter 对象上
            painter.setBrush(brush);
            //if(i==0)
            //painter.fillRect(rect,brush);
            painter.drawRect(startX+i*W/num,startY+j*H/num,W/num,H/num);
            painter.setPen(qRgb(0, 125, 125));
            painter.drawText(startX+i*W/num+H/num/2,startY+j*H/num+H/num/2,QString::number(jz[num*j+i]));
            qDebug()<<i<<" "<<j<<" "<<tmp->sum;
            tmp=tmp->pre;

        }

        free(jz);

        emit showSum(treed->getBest()->sum);

       // painter.draw

    }

}

四、效果

在这里插入图片描述寻找最大SUM路径及计算SUM值
在这里插入图片描述
完整源码下载 源码.rar

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值