题目
从一个数塔中找出一条路径,使路径上的数组和最小
代码
#include<iostream>
using namespace std;
int arr[100][100];//存储数塔的数组
int step[100][100];//记录步数的数组,即往哪个方向走
int calculatearr[100][100];//用于记录计算步数的数组
int layer;//层数
int k = 1;//这是用于输出层数时判断到第几层了
void manage();
void outAndNext(int x,int i,int j);
//初始化函数
void initialize(){//将数组中的元素全部初始化为0
for(int i = 0;i < 100;i ++){
for(int j = 0;j < 100;j ++){
arr[i][j] = 0;
step[i][j] = 0;
calculatearr[i][j] = 0;
}
}
}
//输入函数
void input(){
cout<<"请输入数塔层数:";
cin>>layer;
for(int i = 1;i <= layer;i ++){
for(int j = 1;j <= i;j ++){
cin>>arr[i][j];
}
}
manage();//处理数组
}
//处理计算数组,使得最底层与数塔的值一致
void manage(){
for(int j = 1;j <= layer;j ++){
calculatearr[layer][j] = arr[layer][j];
}
}
//计算具体的步数
void startToJudge(){
for(int i = layer - 1;i > 0; i --){
for(int j = 1;j <= i;j ++){
calculatearr[i][j] = arr[i][j] + min(calculatearr[i + 1][j],calculatearr[i + 1][j + 1]);
calculatearr[i + 1][j] > calculatearr[i + 1][j + 1]? (step[i][j] = 1):(step[i][j] = 0);
}
}
}
//输出向左走还是向右走
void everyStep(int i, int j){
if(k == layer - 1){
if(calculatearr[i][j] == 0)
cout<<"向左"<<endl;
else
cout<<"向右"<<endl;
}
else if(k <= layer){
outAndNext(step[i][j],i,j);
}
}
void outAndNext(int x,int i,int j){
if(x == 0){
k++;
cout<<"向左-->";
everyStep(i + 1,j);
}
else{
k++;
cout<<"向右-->";
everyStep(i + 1,j + 1);
}
}
//输出数塔原型
void outputarr(){
for(int i = 1;i <= layer;i ++){
for(int j = layer - i;j >= 0;j --){
cout<<" ";
}
for(int z = 1;z <= i;z++){
cout<<arr[i][z]<<" ";
}
cout<<endl;
}
}
int main(){
initialize();//初始化数组
input();//输入函数
startToJudge();//开始判断
outputarr();//输出数塔原型
cout<<"该数塔的最小值为:"<<calculatearr[1][1]<<endl;
cout<<"走法为:";
everyStep(1,1);
}
运行截图
调用outputarr()用来输出数塔原本的样子
调用startToJudge()来计算并填充calculatearr数组,在这个数组的[1][1]为最优解(即数塔最短的一条路径)
everystep()用来输出向哪个方向走,主要是根据step[][]数组进行判断,从而输出
求数塔最大值
只需要修改startToJudge()函数的其中两句(第二个for循环中的)
calculatearr[i][j] = arr[i][j] + max(calculatearr[i + 1][j],calculatearr[i + 1][j + 1]);
calculatearr[i + 1][j] > calculatearr[i + 1][j + 1]? (step[i][j] = 0):(step[i][j] = 1);