拉丁矩阵问题 利用回溯法的C++实现方案

这两天正好在赶算法设计的作业,这里把做的几个需要写代码的题放上来,方便以后查看。
1.题目要求
《拉丁矩阵问题 利用回溯法的C++实现方案》

2.算法思想
这个题目基本思想是 利用回溯法,对于 m 行 n 列, 本质上就是一个二维数组, 我们可以将问题的解写成 x[1],x[2],x[3] … x[m*n], 那么对于每个点 x[i] 的取值实际上是 [1, n], 套用回溯法的算法框架,这里的 约束条件 ,就是同行,同列 没有相同的取值, 并且这里没有优化目标,只要类似 N后问题找出所有解就可以了。

另外,回溯时候的边界条件,需要特别注意一下,由于我们把二维数组当作一维数组进行实现, 下标从 0 开始, 理论上到 m*n-1就应该结束了,一开始没怎么注意,导致调试了好久 *23333333333*

3.算法实现源码:

3.1 LatiMatrix.h

// -------------------------【chp 5 HW 拉丁矩阵 宝石排列 】----------------------
// @ author : zhyh2010
// @ date : 20150524
// @ version : 1.0
// @ description : 有n种不同形状的宝石,每种都足够多,现要求将他们排列成
// m行 n 列 的矩阵 (m <= n) 使每行,每列 中的宝石形状不同
// 求, 给定 m,n 时候有多少种算法
// @ idea : 回溯法
// -----------------------------------【end tip】-------------------------------

#pragma once
class CLatiMatrix
{
public:
    CLatiMatrix();
    ~CLatiMatrix();

    int solve();

private:
    void BackTrace(int id);
    void output();
    bool isOK(int row, int col);

    void ReadFile();
    void WriteFile();

private:
    int m_m;
    int m_n;
    int ** m_matrix;

    int m_solution_num;
};

3.2.LatiMatrix.cpp

#include "LatiMatrix.h"
#include <cstdio>
#include <cstdlib>
#include <fstream>


CLatiMatrix::CLatiMatrix()
{
    m_m = 0;
    m_n = 0;
    m_matrix = NULL;

    m_solution_num = 0;
}


CLatiMatrix::~CLatiMatrix()
{
    for (int i = 0; i != m_n; i++)
    {
        if (m_matrix[i])
            delete m_matrix[i];
    }

    if (m_matrix)
        delete [] m_matrix;
}

void CLatiMatrix::BackTrace(int id)
{
    // ===============【这里一开始写的时候没有加 = 号 导致出问题】=================
    if (id >= m_m * m_n)
    {
        output();
        return;
    }

    int row = id / m_n;
    int col = id % m_n;

    for (int k = 0; k != m_n; k++)
    {       
        m_matrix[row][col] = k;

        if (isOK(row, col))
        {
            id++;
            BackTrace(id);
            id--;
        }
    }
}

void CLatiMatrix::output()
{
    m_solution_num++;
}

bool CLatiMatrix::isOK(int row, int col)
{
    int k = m_matrix[row][col];

    for (int i = 0; i != col; i++)
        if (k == m_matrix[row][i])
            return false;

    for (int i = 0; i != row; i++)
        if (k == m_matrix[i][col])
            return false;

    return true;
}

void CLatiMatrix::ReadFile()
{
    std::ifstream infile("input.txt");
    infile >> m_m >> m_n;

    m_matrix = new int *[m_m];
    for (int i = 0; i != m_n; i++)
    {
        m_matrix[i] = new int[m_n];
        memset(m_matrix[i], 0, sizeof(m_matrix[i]));
    }
}

void CLatiMatrix::WriteFile()
{
    std::ofstream outfile("output.txt");
    outfile << m_solution_num << std::endl;
}

int CLatiMatrix::solve()
{
    ReadFile();

    BackTrace(0);

    WriteFile();

    return m_solution_num;
}

3.3.Main.cpp

// -------------------------【chp 5 HW 拉丁矩阵 宝石排列】----------------------
// @ author : zhyh2010
// @ date : 20150524
// @ version : 1.0
// @ description : 有n种不同形状的宝石,每种都足够多,现要求将他们排列成
// m行 n 列 的矩阵 (m <= n) 使每行,每列 中的宝石形状不同
// 求, 给定 m,n 时候有多少种算法
// @ idea : 回溯法
// -----------------------------------【end tip】-------------------------------

#include "LatiMatrix.h"
#include <iostream>

void main()
{
    CLatiMatrix instance;
    int res = instance.solve();
    std::cout << "res = " << res << std::endl;
}
    原文作者:回溯法
    原文地址: https://blog.csdn.net/zhyh1435589631/article/details/45974415
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞