动态规划算法(n阶整数矩阵,从子行、子列、子斜线中找小于整数k的最长线)

斜三角最后没有实现动态规划,如果你有思路,麻烦留言指点,谢谢。

#include <iostream>
#include <sstream>
#include <map>

using namespace std;

int main() {
    int n, k_global; //n维矩阵,k是需要小于等于的数

    int max_row; //储存行最大的直线长度
    int max_line; //储存列最大的直线长度
    int max_up_tri; //储存上三角最大的直线长度
    int max_down_tri; //储存下三角最大的直线长度
    int anti_max_up_tri; //储存反上三角最大的直线长度
    int anti_max_down_tri; //储存反下三角最大的直线长度

    int sum; //计算行列斜三角的和

    int real_max_row = 0; //储存行全局最大值
    int real_max_line = 0; //储存列全局最大值
    int real_max_up_tri = 0; //储存上三角全局最大值
    int real_max_down_tri = 0; //储存下三角全局最大值
    int anti_real_max_up_tri = 0; //储存反上三角全局最大值
    int anti_real_max_down_tri = 0; //储存反下三角全局最大值

    string name; //储存起始坐标和终止坐标 例如(0,0)到(1,1),则为"0011"
    map<string, int> name_arr_row; //行 储存name字符串和它对应的值(小于等于k的那个值)
    map<string, int> name_arr_line; //列 储存name字符串和它对应的值(小于等于k的那个值)
    map<string, int> name_arr_up_tri; //上三角 储存name字符串和它对应的值(小于等于k的那个值)
    map<string, int> name_arr_down_tri; //下三角 储存name字符串和它对应的值(小于等于k的那个值)
    map<string, int> anti_name_arr_up_tri; //反上三角 储存name字符串和它对应的值(小于等于k的那个值)
    map<string, int> anti_name_arr_down_tri; //反下三角 储存name字符串和它对应的值(小于等于k的那个值)

    cout << ("请输入矩阵维数n:");
    cin >> n;
    cout << ("请输入k:");
    cin >> k_global;
    //生成n维的随机数组
    int arr[n][n];
    cout << "矩阵为:" << endl;
    for (int j = 0; j < n; ++j) {
        for (int i = 0; i < n; ++i) {
            arr[j][i] = rand() % 10;
            cout << arr[j][i] << " ";
            if (i == n - 1)
                cout << endl;
        }
    }

    //计算行间的最大值
    for (int i = 0; i < n; ++i) { //行
        for (int j = 0; j < n; ++j) { //列
            sum = 0;
            for (int k = j; k < n; ++k) { //保持和j一样
                sum += arr[i][k];
                if (sum <= k_global) {
                    ostringstream ostr;
                    ostr << i << j << i << k;
                    name = ostr.str();
                    max_row = k - j + 1;
                    if (max_row > real_max_row) {
                        real_max_row = max_row;
                    }
                    name_arr_row.insert(pair<string, int>(name, max_row));
                    if (max_row == n) {
                        break;
                    }
                } else
                    break;
            }
            if (max_row == n)
                break;
        }
    }

    //计算列间最大长度
    for (int j = 0; j < n; ++j) { //列
        for (int i = 0; i < n; ++i) { //行
            sum = 0;
            for (int k = i; k < n; ++k) { //保持和j一样
                sum += arr[k][j];
                if (sum <= k_global) {
                    ostringstream ostr;
                    ostr << i << j << k << j;
                    name = ostr.str();
                    max_line = k - i + 1;
                    if (max_line > real_max_line) {
                        real_max_line = max_line;
                    }
                    name_arr_line.insert(pair<string, int>(name, max_line));
                    if (max_line == n) {
                        break;
                    }
                } else
                    break;
            }
            if (max_line == n)
                break;
        }
    }

    //计算上三角间最大长度
    for (int f = 0; f < n; f++) {
        for (int g = 0, e = f; g < n && e < n; g++, e++) {//e和f保持一致,g表示行,f表示列
            sum = 0;
            for (int i = g, j = (g + f); i < n && j < n; i++, j++) { // i表示行,j表示列
                sum += arr[i][j];
                if (sum <= k_global) {
                    ostringstream ostr;
                    ostr << g << g + f << i << j;
                    name = ostr.str();
                    max_up_tri = i - g + 1;
                    if (max_up_tri > real_max_up_tri) {
                        real_max_up_tri = max_up_tri;
                    }
                    name_arr_up_tri.insert(pair<string, int>(name, max_up_tri));
                    if (max_up_tri == n) {
                        break;
                    }
                } else
                    break;
            }
            if (max_up_tri == n)
                break;
        }
    }

    //计算下三角间最大长度
    for (int f = 0; f < n; f++) {
        for (int g = 0, e = f; g < n && e < n; g++, e++) {//e和f保持一致,g表示行,f表示列
            sum = 0;
            for (int i = f + g, j = g; i < n && j < n; i++, j++) { // i表示行,j表示列
                sum += arr[i][j];
                if (sum <= k_global) {
                    ostringstream ostr;
                    ostr << g + f << g << i << j;
                    name = ostr.str();
                    max_down_tri = i - (g + f) + 1;
                    if (max_down_tri > real_max_down_tri) {
                        real_max_down_tri = max_down_tri;
                    }
                    name_arr_down_tri.insert(pair<string, int>(name, max_down_tri));
                    if (max_down_tri == n) {
                        break;
                    }
                } else
                    break;
            }
            if (max_down_tri == n)
                break;
        }
    }

    //计算反上三角的最大长度
    for (int l = 1; l <= n; ++l) { //控制趟数
        sum = 0;
        int count = 0;
        for (int i = l - 1, j = 0; i < n && j < n && count < l; i++) {
            for (int x = i, y = 0; x < n && x >= 0 && y < n && count < l; --x, y++) {
                sum += arr[x][y];
                if (sum <= k_global) {
                    ostringstream ostr;
                    ostr << i << j << x << y;
                    name = ostr.str();
                    anti_max_up_tri = i - x + 1;
                    if (anti_max_up_tri > anti_real_max_up_tri) {
                        anti_real_max_up_tri = anti_max_up_tri;
                    }
                    anti_name_arr_up_tri.insert(pair<string, int>(name, anti_max_up_tri));
                    if (anti_max_up_tri == n) {
                        break;
                    }
                    count++;
                } else {
                    count = 0;
                    break;
                }
            }
        }
    }

    //计算反下三角的最大长度
    for (int l = 4; l >= 0; --l) { //控制趟数
        sum = 0;
        for (int i = l - 1, j = n - 1; i < n && j < n; i--) {
            for (int x = i, y = j; x < n && x >= 0 && y < n && y >= 0; ++x, y--) {
                sum += arr[x][y];
                if (sum <= k_global) {
                    ostringstream ostr;
                    ostr << i << j << x << y;
                    name = ostr.str();
                    anti_max_down_tri = abs(i - x) + 1;
                    if (anti_max_down_tri > anti_real_max_down_tri) {
                        anti_real_max_down_tri = anti_max_down_tri;
                    }
                    anti_name_arr_down_tri.insert(pair<string, int>(name, anti_max_down_tri));
                    if (anti_max_down_tri == n) {
                        break;
                    }
                } else {
                    break;
                }
            }
        }
    }

    cout << "行方向最长线的坐标为" << endl;
    //寻找最大值
    for (auto i = name_arr_row.begin(); i != name_arr_row.end(); i++) {
        if (i->second == real_max_row) {
            cout << "(" << (i->first)[0] << ", " << i->first[1] << ")->("
                 << i->first[2] << ", " << i->first[3] << ")" << endl;
        }
    }
    cout << "行最长线的长度为:" << real_max_row << endl;
    cout << "列方向最长线的坐标为" << endl;
    for (auto i = name_arr_line.begin(); i != name_arr_line.end(); i++) {
        if (i->second == real_max_line) {
            cout << "(" << (i->first)[0] << ", " << i->first[1] << ")->("
                 << i->first[2] << ", " << i->first[3] << ")" << endl;
        }
    }
    cout << "列最长线的长度为:" << real_max_line << endl;
    cout << "上三角方向最长线的坐标为" << endl;
    for (auto i = name_arr_up_tri.begin(); i != name_arr_up_tri.end(); i++) {
        if (i->second == real_max_up_tri) {
            cout << "(" << (i->first)[0] << ", " << i->first[1] << ")->("
                 << i->first[2] << ", " << i->first[3] << ")" << endl;
        }
    }
    cout << "上三角最长线的长度为:" << real_max_up_tri << endl;

    cout << "下三角方向最长线的坐标为" << endl;
    for (auto i = name_arr_down_tri.begin(); i != name_arr_down_tri.end(); i++) {
        if (i->second == real_max_down_tri) {
            cout << "(" << (i->first)[0] << ", " << i->first[1] << ")->("
                 << i->first[2] << ", " << i->first[3] << ")" << endl;
        }
    }
    cout << "下三角最长线的长度为:" << real_max_down_tri << endl;

    cout << "反上三角方向最长线的坐标为" << endl;
    for (auto i = anti_name_arr_up_tri.begin(); i != anti_name_arr_up_tri.end(); i++) {
        if (i->second == anti_real_max_up_tri) {
            cout << "(" << (i->first)[0] << ", " << i->first[1] << ")->("
                 << i->first[2] << ", " << i->first[3] << ")" << endl;
        }
    }
    cout << "反上三角最长线的长度为:" << anti_real_max_up_tri << endl;

    cout << "反下三角方向最长线的坐标为" << endl;
    for (auto i = anti_name_arr_down_tri.begin(); i != anti_name_arr_down_tri.end(); i++) {
        if (i->second == anti_real_max_down_tri) {
            cout << "(" << (i->first)[0] << ", " << i->first[1] << ")->("
                 << i->first[2] << ", " << i->first[3] << ")" << endl;
        }
    }
    cout << "反下三角最长线的长度为:" << anti_real_max_down_tri << endl;
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Bean冷的心

你的鼓励将是我前进的动力~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值