拉丁矩阵问题 利用回溯法的C++实现方案
2015-05-25 20:53
537 查看
这两天正好在赶算法设计的作业,这里把做的几个需要写代码的题放上来,方便以后查看。
1.题目要求
![](https://oscdn.geek-share.com/Uploads/Images/Content/201911/15/e8518b6561f11865769958e00a64b67e)
2.算法思想
这个题目基本思想是 利用回溯法,对于 m 行 n 列, 本质上就是一个二维数组, 我们可以将问题的解写成 x[1],x[2],x[3] … x[m*n], 那么对于每个点 x[i] 的取值实际上是 [1, n], 套用回溯法的算法框架,这里的 约束条件 ,就是同行,同列 没有相同的取值, 并且这里没有优化目标,只要类似 N后问题找出所有解就可以了。
3.1 LatiMatrix.h
3.2.LatiMatrix.cpp
3.3.Main.cpp
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; }
相关文章推荐
- 从易到难编写C++程序,(6)问题:利用问题(5)的随机数生成实现发牌
- 从易到难编写C++程序,(7)问题:利用问题(6)的发牌,实现24点游戏
- 从易到难编写C++程序,(8)问题:实现一个矩阵类
- opencv2.0以后新增C++接口的 Mat矩阵 单行赋值及矩阵合并的问题与实现(苦心研究多天才解决!)
- Windows Phone 8 学习志(探索问题一:如何简单利用Windows Phone Runtime Component项目类型实现C#和C++交互)
- Python中利用列表推导式实现矩阵置换时发现的"问题"
- 利用C++实现矩阵的相加/相称/转置/求鞍点
- 【算法】 输入n 输出一个n*n的zigzag矩阵 利用c++实现
- 利用模拟退火算法求解TSP问题(C++实现)
- 图着色问题 配色方案 C++实现 回溯法
- 最小重量问题的分支界限法的C++实现方案
- 问题五十二:怎么用C++实现矩阵运算
- C++利用vector容器实现最大最小元问题
- 0/1背包问题 - 回溯法(C++实现)
- C++实现矩阵链乘法利用动态规划及运行实例结果
- C++实现矩阵链乘法利用动态规划及运行实例结果
- C++实现矩阵链乘法利用动态规划及运行实例结果
- C++实现矩阵链乘法利用动态规划及运行实例结果
- C++实现矩阵链乘法利用动态规划及运行实例结果
- C++实现矩阵链乘法利用动态规划及运行实例结果