您的位置:首页 > 编程语言 > C语言/C++

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

2015-05-25 20:53 537 查看
这两天正好在赶算法设计的作业,这里把做的几个需要写代码的题放上来,方便以后查看。

1.题目要求



2.算法思想

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

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

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: