[算法设计与分析]3.2.5构造趣味矩阵(规律阵+螺旋阵+魔方阵)
2018-03-28 17:31
423 查看
#include<stdio.h> #include<iostream> using namespace std; const int N = 5; void RegularMatrix(); void ScrewMatrix1(); void ScrewMatrix2(); void MagicMatrix(); int main () { RegularMatrix(); ScrewMatrix1(); ScrewMatrix2(); MagicMatrix(); } void RegularMatrix() { int i, j; int a[N + 1][N + 1]; for(i = 1; i <= N; i++) { for(j = 1; j <= N; j++)//根据两条对角线与行列下标的关系 进行划分 { if(i == j || i + j == N + 1) a[i][j] = 0; if(i + j < N + 1 && i < j) a[i][j] = 1; if(i + j < N + 1 && i > j) a[i][j] = 2; if(i + j > N + 1 && i < j) a[i][j] = 3; if(i + j > N + 1 && i > j) a[i][j] = 4; } } for(i = 1; i <= N; i++) { for(j = 1; j <= N; j++) { cout << a[i][j] << " "; } cout << endl; } cout << endl; } void ScrewMatrix1() { int N = 4; int a[N + 1][N + 1]; int num = 1; int circle, left, lower, right, upper; for(circle = 1; circle <= N / 2; circle++)//circle代表的是第几圈 { for(left = circle; left <= N - circle; left++)//left代表的是左侧 left的初始值一定是一个变化的数 //否则无法做到在circle循环赋值 同时left的最大值一定与n和circle相关 { a[left][circle] = num++; } for(lower = circle; lower <= N - circle; lower++)//lower的初始值一定与circle相关 是一个变化的值 //lower的最大值与circle相关 也等于此时的left(循环结束条件是left+1之后的结果) { a[N + 1 - circle][lower] = num++;//下边的行号与left的最大值相同 列号不断变化 } for(right = lower; right >= circle + 1; right--)//right的最小值与circle相关 { a[right][N + 1 - circle] = num++; } for(upper = N + 1 - circle; upper >= circle + 1; upper--)//行号不变 { a[circle][upper] = num++; } } if(N % 2) { a[(N + 1) / 2][(N + 1) / 2] = N * N; } for(int i = 1; i <= N; i++) { for(int j = 1; j <= N; j++) printf("%3d", a[i][j]); cout <<endl; } cout << endl; } //通过引入数组b,变量t和k将一圈中的上下左右4种变化情况构造成一个循环不变式 void ScrewMatrix2() { int N = 4; int a[N + 1][N + 1], b[2] = {0, 1};//b[0]表示存储矩阵的数组a的行下标,b[1]表示列下标 int i, j, k, y; k = N; int t = 1; int num = 1; while(num <= N * N) {//规模为N的矩阵的一圈共有4N-4个元素 而本算法的半圈是不对称的(为了构成循环,因为循环的每一圈矩阵规模都不同) for(y = 1; y <= 2 * k - 1; y++)//y用作循环变量模拟半圈数据处理的过程 {//在每个半圈中 当y=1->k的时候 y/(k+1)的值始终为0 这样列下标b[1]不会发生变化 而行下标b[0]则不断地+t变化(根据t的正负不同) //当y=k+1->2k-1时 行下标b[0]不会发生变化b[1]随t变化 b[y / (k + 1)] = b[y / (k + 1)] + t;//t=1时处理左下角 t=-1时处理右下角 a[b[0]][b[1]] = num++; } k--; t = -t; } for(int i = 1; i <= N; i++) { for(int j = 1; j <= N; j++) printf("%3d", a[i][j]); cout <<endl; } cout << endl; } void MagicMatrix() { int N = 3, m; int a[N + 1][N + 1] = {0}; int i = 1, j = (N + 1) / 2;//i,j分别代表行列坐标 int prei, prej; for(m = 1; m <= N * N; m++)//m表示要填入的数 { a[i][j] = m; prei = i;//因为涉及到对当前元素的前一个元素的操作 因此需要记录之前元素的行列下标 prej = j; i = i - 1;//按照魔方阵的规则 j = j - 1; if(i == 0)//行下标或者列下标出界 i = N; if(j == 0) j = N; if(a[i][j])//该位置已经有数 { i = prei + 1; j = prej; } } for(int i = 1; i <= N; i++) { for(int j = 1; j <= N; j++) printf("%3d", a[i][j]); cout <<endl; } }
相关文章推荐
- 算法分析与设计——矩阵连乘问题
- 算法分析与设计矩阵连乘问题
- 算法设计与分析--矩阵连乘顺序问题…
- 【算法分析与设计】【第六周】690. Employee Importance
- 算法分析与设计week08--738. Monotone Increasing Digits
- 算法分析与设计课程作业第五周#1
- 算法分析与设计第六周
- 【计算机算法分析】动态规划法——矩阵连乘问题
- 算法分析与设计第二周习题:分治算法之P215,P169,P53
- n阶Hanoi塔问题 - 算法设计与分析实验1
- 算法分析与设计期末总结(1)
- 动态规划法之投资问题_算法分析与设计
- Stanford公开课之算法:设计与分析——(第一周) Programming Question-1
- 南邮算法分析和实验设计1 分而治之
- 算法分析与设计第七周:134. Gas Station
- 算法分析与设计丨第七周丨LeetCode(11)——Candy(Hard)
- [置顶] 斗地主算法的设计与实现--项目介绍&如何定义和构造一张牌
- [算法分析与设计] leetcode 每周一题: 078. Subsets
- 算法分析与设计——LeetCode:16. 3Sum Closest
- 【算法】算法分析与设计的基本方法