一、题目原型:
有nn个格子,每个格子里有正数或者0,从最左上角往最右下角走,只能向下和向右,从A点走到B点,把所有经过的格子的数加起来,求最大值SUM。 (80分)
程序实现:
1)用QT、MFC或windows SDK实现对话框:首先n的输入框,输入以后点确定后,弹出 NN矩阵的设置框。
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