C语言经典算法-9

news2024/12/29 1:12:49

文章目录

  • 其他经典例题跳转链接
    • 46.稀疏矩阵
    • 47.多维矩阵转一维矩阵
    • 48.上三角、下三角、对称矩阵
    • 49.奇数魔方阵
    • 50.4N 魔方阵
    • 51.2(2N+1) 魔方阵

其他经典例题跳转链接

C语言经典算法-1
1.汉若塔 2. 费式数列 3. 巴斯卡三角形 4. 三色棋 5. 老鼠走迷官(一)6. 老鼠走迷官(二)7. 骑士走棋盘8. 八皇后9. 八枚银币10. 生命游戏

C语言经典算法-2
字串核对、双色、三色河内塔、背包问题(Knapsack Problem)、蒙地卡罗法求 PI、Eratosthenes筛选求质数

C语言经典算法-3
超长整数运算(大数运算)、长 PI、最大公因数、最小公倍数、因式分解、完美数、阿姆斯壮数

C语言经典算法-4
最大访客数、中序式转后序式(前序式)、后序式的运算、洗扑克牌(乱数排列)、Craps赌博游戏

C语言经典算法-5
约瑟夫问题(Josephus Problem)、排列组合、格雷码(Gray Code)、产生可能的集合、m元素集合的n个元素子集

C语言经典算法-6
数字拆解、得分排行,选择、插入、气泡排序、Shell 排序法 - 改良的插入排序、Shaker 排序法 - 改良的气泡排序

C语言经典算法-7
排序法 - 改良的选择排序、快速排序法(一)、快速排序法(二)、快速排序法(三)、合并排序法

C语言经典算法-8
基数排序法、循序搜寻法(使用卫兵)、二分搜寻法(搜寻原则的代表)、插补搜寻法、费氏搜寻法

C语言经典算法-9
稀疏矩阵、多维矩阵转一维矩阵、上三角、下三角、对称矩阵、奇数魔方阵、4N 魔方阵、2(2N+1) 魔方阵

46.稀疏矩阵

说明
如果在矩阵中,多数的元素并没有资料,称此矩阵为稀疏矩阵(sparse matrix),由于矩阵在程式中常使用二维阵列表示,二维阵列的大小与使用的记忆体空间成正比,如果多数的元素没有资料,则会造成记忆体空间的浪费,为 此,必须设计稀疏矩阵的阵列储存方式,利用较少的记忆体空间储存完整的矩阵资讯。
解法
在这边所介绍的方法较为简单,阵列只储存矩阵的行数、列数与有资料的索引位置及其值,在需要使用矩阵资料时,再透过程式运算加以还原,例如若矩阵资料如下 ,其中0表示矩阵中该位置没有资料:
0 0 0 0 0 0
0 3 0 0 0 0
0 0 0 6 0 0
0 0 9 0 0 0
0 0 0 0 12 0

这个矩阵是5X6矩阵,非零元素有4个,您要使用的阵列第一列记录其列数、行数与非零元素个数:
5 6 4

阵列的第二列起,记录其位置的列索引、行索引与储存值:
1 1 3
2 3 6
3 2 9
4 4 12

所以原本要用30个元素储存的矩阵资讯,现在只使用了15个元素来储存,节省了不少记忆体的使用。

#include <stdio.h> 
#include <stdlib.h> 

int main(void) { 
    int num[5][3] = {{5, 6, 4}, 
                     {1, 1, 3}, 
                     {2, 3, 6}, 
                     {3, 2, 9}, 
                     {4, 4, 12}}; 
    int i, j, k = 1; 

    printf("sparse matrix:\n"); 
    for(i = 0; i < 5; i++) { 
        for(j = 0; j < 3; j++) { 
            printf("%4d", num[i][j]); 
        } 
        putchar('\n'); 
    } 

    printf("\nmatrix还原:\n"); 
    for(i = 0; i < num[0][0]; i++) { 
        for(j = 0; j < num[0][1]; j++) { 
            if(k < num[0][2] && 
               i == num[k][0] && j == num[k][1]) { 
                printf("%4d ", num[k][2]); 
                k++; 
            } 
            else 
                printf("%4d ", 0); 
        } 
        putchar('\n'); 
    } 

    return 0; 
} 

47.多维矩阵转一维矩阵

说明
有的时候,为了运算方便或资料储存的空间问题,使用一维阵列会比二维或多维阵列来得方便,例如上三角矩阵、下三角矩阵或对角矩阵,使用一维阵列会比使用二维阵列来得节省空间。
解法
以二维阵列转一维阵列为例,索引值由0开始,在由二维阵列转一维阵列时,我们有两种方式:「以列(Row)为主」或「以行(Column)为主」。由于 C/C++、Java等的记忆体配置方式都是以列为主,所以您可能会比较熟悉前者(Fortran的记忆体配置方式是以行为主)。

以列为主的二维阵列要转为一维阵列时,是将二维阵列由上往下一列一列读入一维阵列,此时索引的对应公式如下所示,其中row与column是二维阵列索引,loc表示对应的一维阵列索引:
loc = column + row*行数

以行为主的二维阵列要转为一维阵列时,是将二维阵列由左往右一行一行读入一维阵列,此时索引的对应公式如下所示:
loc = row + column*列数

公式的推导您画图看看就知道了,如果是三维阵列,则公式如下所示,其中i(个数u1)、j(个数u2)、k(个数u3)分别表示三维阵列的三个索引:

以列为主:loc = iu2u3 + ju3 + k
以行为主:loc = k
u1u2 + ju1 + i

更高维度的可以自行依此类推,但通常更高维度的建议使用其它资料结构(例如物件包装)会比较具体,也不易搞错。

在C/C++中若使用到指标时,会遇到指标运算与记忆体空间位址的处理问题,此时也是用到这边的公式,不过必须在每一个项上乘上资料型态的记忆体大小。

#include <stdio.h> 
#include <stdlib.h> 

int main(void) { 
    int arr1[3][4] = {{1, 2, 3, 4}, 
                     {5, 6, 7, 8}, 
                     {9, 10, 11, 12}}; 
    int arr2[12] = {0}; 
    int row, column, i; 

    printf("原二维资料:\n"); 
    for(row = 0; row < 3; row++) { 
        for(column = 0; column < 4; column++) { 
            printf("%4d", arr1[row][column]); 
        } 
        printf("\n"); 
    } 

    printf("\n以列为主:"); 
    for(row = 0; row < 3; row++) { 
        for(column = 0; column < 4; column++) { 
            i = column + row * 4; 
            arr2[i] = arr1[row][column]; 
        } 
    } 
    for(i = 0; i < 12; i++) 
        printf("%d ", arr2[i]); 

    printf("\n以行为主:"); 
    for(row = 0; row < 3; row++) { 
        for(column = 0; column < 4; column++) { 
            i = row + column * 3; 
            arr2[i] = arr1[row][column]; 
        } 
    } 
    for(i = 0; i < 12; i++) 
        printf("%d ", arr2[i]); 

    printf("\n"); 

    return 0; 
} 

48.上三角、下三角、对称矩阵

说明
上三角矩阵是矩阵在对角线以下的元素均为0,即Aij = 0,i > j,例如:
1 2 3 4 5
0 6 7 8 9
0 0 10 11 12
0 0 0 13 14
0 0 0 0 15

下三角矩阵是矩阵在对角线以上的元素均为0,即Aij = 0,i < j,例如:
1 0 0 0 0
2 6 0 0 0
3 7 10 0 0
4 8 11 13 0
5 9 12 14 15

对称矩阵是矩阵元素对称于对角线,例如:
1 2 3 4 5
2 6 7 8 9
3 7 10 11 12
4 8 11 13 14
5 9 12 14 15

上三角或下三角矩阵也有大部份的元素不储存值(为0),我们可以将它们使用一维阵列来储存以节省储存空间,而对称矩阵因为对称于对角线,所以可以视为上三角或下三角矩阵来储存。
解法
假设矩阵为nxn,为了计算方便,我们让阵列索引由1开始,上三角矩阵化为一维阵列,若以列为主,其公式为:loc = n*(i-1) - i*(i-1)/2 + j
化为以行为主,其公式为:loc = j*(j-1)/2 + i

下三角矩阵化为一维阵列,若以列为主,其公式为:loc = i*(i-1)/2 + j

若以行为主,其公式为:loc = n*(j-1) - j*(j-1)/2 + i
公式的导证其实是由等差级数公式得到,您可以自行绘图并看看就可以导证出来,对于C/C++或Java等索引由0开始的语言来说,只要将i与j各加1,求得loc之后减1即可套用以上的公式。

#include <stdio.h> 
#include <stdlib.h> 
#define N 5 

int main(void) { 
    int arr1[N][N] = { 
        {1, 2, 3,  4,   5}, 
        {0, 6, 7,  8,   9}, 
        {0, 0, 10, 11, 12}, 
        {0, 0, 0,  13, 14}, 
        {0, 0, 0,  0,  15}}; 

    int arr2[N*(1+N)/2] = {0}; 

    int i, j, loc = 0; 

    printf("原二维资料:\n"); 
    for(i = 0; i < N; i++) { 
        for(j = 0; j < N; j++) { 
            printf("%4d", arr1[i][j]); 
        } 
        printf("\n"); 
    } 

    printf("\n以列为主:"); 
    for(i = 0; i < N; i++) { 
        for(j = 0; j < N; j++) { 
            if(arr1[i][j] != 0) 
                arr2[loc++] = arr1[i][j]; 
        } 
    } 
    for(i = 0; i < N*(1+N)/2; i++) 
        printf("%d ", arr2[i]); 

    printf("\n输入索引(i, j):"); 
    scanf("%d, %d", &i, &j); 
    loc = N*i - i*(i+1)/2 + j; 
    printf("(%d, %d) = %d", i, j, arr2[loc]); 

    printf("\n"); 
    return 0; 
} 

49.奇数魔方阵

说明
将1到n(为奇数)的数字排列在nxn的方阵上,且各行、各列与各对角线的和必须相同,如下所示:
在这里插入图片描述

解法

填魔术方阵的方法以奇数最为简单,第一个数字放在第一行第一列的正中央,然后向右(左)上填,如果右(左)上已有数字,则向下填,如下图所示:
在这里插入图片描述

一般程式语言的阵列索引多由0开始,为了计算方便,我们利用索引1到n的部份,而在计算是向右(左)上或向下时,我们可以将索引值除以n值,如果得到余数为1就向下,否则就往右(左)上,原理很简单,看看是不是已经在同一列上绕一圈就对了。

#include <stdio.h> 
#include <stdlib.h> 

#define N 5 

int main(void) { 
    int i, j, key; 
    int square[N+1][N+1] = {0}; 

    i = 0; 
    j = (N+1) / 2; 

    for(key = 1; key <= N*N; key++) { 
        if((key % N) == 1) 
            i++; 
        else { 
            i--; 
            j++; 
        } 

        if(i == 0) 
            i = N; 
        if(j > N) 
            j = 1; 

        square[i][j] = key; 
    } 

    for(i = 1; i <= N; i++) { 
        for(j = 1; j <= N; j++) 
            printf("%2d ", square[i][j]); 
    } 

    return 0; 
} 

50.4N 魔方阵

说明
与 奇数魔术方阵 相同,在于求各行、各列与各对角线的和相等,而这次方阵的维度是4的倍数。
解法
先来看看4X4方阵的解法:

在这里插入图片描述

简单的说,就是一个从左上由1依序开始填,但遇对角线不填,另一个由左上由16开始填,但只填在对角线,再将两个合起来就是解答了;如果N大于2,则以 4X4为单位画对角线:
在这里插入图片描述

至于对角线的位置该如何判断,有两个公式,有兴趣的可以画图印证看看,如下所示:
左上至右下:j % 4 == i % 4
右上至左下:(j % 4 + i % 4) == 1

#include <stdio.h> 
#include <stdlib.h> 

#define N 8 

int main(void) { 
    int i, j; 
    int square[N+1][N+1] = {0}; 

    for(j = 1; j <= N; j++) { 
        for(i = 1; i <= N; i++){ 
            if(j % 4 == i % 4 || (j % 4 + i % 4) == 1) 
                square[i][j] = (N+1-i) * N -j + 1; 
            else 
                square[i][j] = (i - 1) * N + j; 
        } 
    } 

    for(i = 1; i <= N; i++) { 
        for(j = 1; j <= N; j++) 
            printf("%2d ", square[i][j]); 
        printf("\n"); 
    } 

    return 0; 
} 

51.2(2N+1) 魔方阵

说明方阵的维度整体来看是偶数,但是其实是一个奇数乘以一个偶数,例如6X6,其中6=2X3,我们也称这种方阵与单偶数方阵。
解法如果您会解奇数魔术方阵,要解这种方阵也就不难理解,首先我们令n=2(2m+1),并将整个方阵看作是数个奇数方阵的组合,如下所示:
在这里插入图片描述

首先依序将A、B、C、D四个位置,依奇数方阵的规则填入数字,填完之后,方阵中各行的和就相同了,但列与对角线则否,此时必须在A-D与C- B之间,作一些对应的调换,规则如下:
将A中每一列(中间列除外)的头m个元素,与D中对应位置的元素调换。
将A的中央列、中央那一格向左取m格,并与D中对应位置对调
将C中每一列的倒数m-1个元素,与B中对应的元素对调
举个实例来说,如何填6X6方阵,我们首先将之分解为奇数方阵,并填入数字,如下所示:

在这里插入图片描述

接下来进行互换的动作,互换的元素以不同颜色标示,如下:
在这里插入图片描述

由于m-1的数为0,所以在这个例子中,C-B部份并不用进行对调。

#include <stdio.h> 
#include <stdlib.h> 

#define N 6 
#define SWAP(x,y) {int t; t = x; x = y; y = t;} 

void magic_o(int [][N], int); 
void exchange(int [][N], int); 

int main(void) { 
    int square[N][N] = {0}; 
    int i, j; 

    magic_o(square, N/2); 
    exchange(square, N); 

    for(i = 0; i < N; i++) { 
        for(j = 0; j < N; j++) 
            printf("%2d ", square[i][j]); 
        printf("\n"); 
    } 

    return 0; 
} 

void magic_o(int square[][N], int n) { 
    int count, row, column; 

    row = 0; 
    column = n / 2; 

    for(count = 1; count <= n*n; count++) { 
        square[row][column] = count;            // 填A 
        square[row+n][column+n] = count + n*n;  // 填B 
        square[row][column+n] = count + 2*n*n;  // 填C 
        square[row+n][column] = count + 3*n*n;  // 填D 
        if(count % n == 0) 
            row++; 
        else { 
            row = (row == 0) ? n - 1 : row - 1 ; 
            column = (column == n-1) ? 0 : column + 1; 
        } 
    } 
} 

void exchange(int x[][N], int n) { 
    int i, j; 
    int m = n / 4; 
    int m1 = m - 1; 

    for(i = 0; i < n/2; i++) { 
        if(i != m)  {    
            for(j = 0; j < m; j++)          // 处理规则 1 
                SWAP(x[i][j], x[n/2+i][j]); 
            for(j = 0; j < m1; j++)         // 处理规则 2 
                SWAP(x[i][n-1-j], x[n/2+i][n-1-j]); 
        } 
        else {  // 处理规则 3 
            for(j = 1; j <= m; j++) 
                SWAP(x[m][j], x[n/2+m][j]); 
            for(j = 0; j < m1; j++) 
                SWAP(x[m][n-1-j], x[n/2+m][n-1-j]); 
        } 
    } 
} 

系列好文,点击链接即可跳转

C语言经典算法-1
1.汉若塔 2. 费式数列 3. 巴斯卡三角形 4. 三色棋 5. 老鼠走迷官(一)6. 老鼠走迷官(二)7. 骑士走棋盘8. 八皇后9. 八枚银币10. 生命游戏

C语言经典算法-8
基数排序法、循序搜寻法(使用卫兵)、二分搜寻法(搜寻原则的代表)、插补搜寻法、费氏搜寻法

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1541073.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【go从入门到精通】for循环控制

作者简介&#xff1a; 高科&#xff0c;先后在 IBM PlatformComputing从事网格计算&#xff0c;淘米网&#xff0c;网易从事游戏服务器开发&#xff0c;拥有丰富的C&#xff0c;go等语言开发经验&#xff0c;mysql&#xff0c;mongo&#xff0c;redis等数据库&#xff0c;设计模…

ssm003在线医疗服务系统+jsp

在线医疗服务系统的设计与实现 摘 要 网络技术和计算机技术发展至今&#xff0c;已经拥有了深厚的理论基础&#xff0c;并在现实中进行了充分运用&#xff0c;尤其是基于计算机运行的软件更是受到各界的关注。加上现在人们已经步入信息时代&#xff0c;所以对于信息的宣传和管…

bevformer转模型经验(需要时序tranformer所有模型都可以参考)

先上bevformer的网络结构图 不难发现&#xff0c;他有两个输入。当前的环视图和历史bev。历史bev是通过历史环视图生成的。也就是说在生成bev特征提取模型这部分被使用了两次。在装模型时候&#xff0c;需要作以下工作&#xff1a; 1 bev特征提取模型单独提出来&#xff0c;转…

用Kimichat学习王庆法老师关于Sora的文章

目录 一 引言:二 提示词方面:三 与Kimi的聊天记录我:假如你是一名大模型方面的专家,提取一下这篇文章的核心观点,用三列表格的形式,https://mp.weixin.qq.com/s/Y-vmxmPu4_-tHaeP35hDJg我:上述文章的一、Spacetime Latent Patches 潜变量时空碎片, 建构视觉语言系统部分…

python处理Excel的方法之xlrd

python处理Excel常用到的模块是xlrd。使用xlrd可以非常方便的处理Excel文档&#xff0c;下面介绍一下基本用法 打开文件 import xlrd data xlrd.open_workbook("c:\\skills.xls") 获取一个工作表 table data.sheet_by_name(uskills) #也可以 table data.sheet_by_…

PTA-练习7

目录 实验8-2-1 找最小的字符串 实验8-2-2 找最长的字符串 实验8-2-8 字符串排序 实验8-2-10 IP地址转换 结构体 实验9-1 计算职工工资 实验9-2 时间换算 实验9-3 计算平均成绩 实验9-5 查找书籍 实验9-8 通讯录排序 实验9-9 有理数比较 实验11-1-1 英文单词排序 …

在 Windows 中安装配置并启动运行 Jenkins【图文详细教程】

安装 Jenkins 的系统要求&#xff1a; 最少 256MB 可用内存最少 1GB 可用磁盘空间JDK 8 / 11 /17&#xff08;Jenkins 是用 Java 写的&#xff0c;打包成 war 包&#xff09; 查看 JDK 的版本 Java JDK 在 Windows 中安装可以参考&#xff1a;https://www.yuque.com/u27599042/…

iscsi网络协议(连接硬件设备)

iscsi概念 iscsi是一种互联网协议&#xff0c;用于将存储设备&#xff08;如硬盘驱动器或磁带驱动器&#xff09;通过网络连接到计算机。它是一种存储区域网络&#xff08;SAN&#xff09;技术&#xff0c;允许服务器通过网络连接到存储设备&#xff0c;就像它们是本地设备一样…

【C++】1596. 火柴棒三角形问题

问题&#xff1a;1596. 火柴棒三角形问题 类型&#xff1a;基本运算、整数运算 题目描述&#xff1a; 如下图所示&#xff0c;摆 1 个火柴棒三角形需要 3 根火柴&#xff0c;那么摆 2 个火柴棒三角形就需要 6 根火柴&#xff0c;请问摆 n 个火柴棒三角形需要多少根火柴&#…

由浅入深一步步了解什么是哈希(概念向)

文章目录 什么是哈希哈希函数直接定址法除留余数法 哈希冲突闭散列线性探测法二次探测法负载因子和闭散列的扩容 开散列开散列的扩容 非整形关键码 什么是哈希 我们来重新认识一下数据查找的过程&#xff1a; 在顺序结构以及平衡树中&#xff0c;记录的关键码与其存储位置之间…

基因在各个细胞系表达情况

从CCLE下载数据得到基因在每个细胞系中的 现在从DepMap: The Cancer Dependency Map Project at Broad Institute 需要先选择Custom Downloads 就可以下载数据进行处理了&#xff1a; rm(list ls()) library(tidyverse) library(ggpubr) rt <- data.table::fread("…

LeetCode每日一题——统计桌面上的不同数字

统计桌面上的不同数字OJ链接&#xff1a;2549. 统计桌面上的不同数字 - 力扣&#xff08;LeetCode&#xff09; 题目&#xff1a; 思路&#xff1a; 这是一个很简单的数学问题&#xff1a; 当n 5时&#xff0c;因为n % 4 1&#xff0c;所以下一天4一定会被放上桌面 当n 4…

SpringBoot 3整合Elasticsearch 8

这里写自定义目录标题 版本说明spring boot POM依赖application.yml配置新建模型映射Repository简单测试完整项目文件目录结构windows下elasticsearch安装配置 版本说明 官网说明 本文使用最新的版本 springboot: 3.2.3 spring-data elasticsearch: 5.2.3 elasticsearch: 8.1…

Unity Mesh简化为Cube mesh

Mesh简化为Cube mesh &#x1f373;食用&#x1f959;子物体独立生成CubeMesh&#x1f96a;合并成一个CubeMesh&#x1f32d;Demo &#x1f373;食用 下载并导入插件&#x1f448;即可在代码中调用。 &#x1f959;子物体独立生成CubeMesh gameObject.ToCubeMesh_Invidual()…

计算机基础系列 —— 汇编语言

Same hardware can run many different programs(Software) 文中提到的所有实现都可以参考&#xff1a;nand2tetris_sol&#xff0c;但是最好还是自己学习课程实现一遍&#xff0c;理解更深刻。 我们在之前的文章里&#xff0c;构建了 Register、RAM 和 ALU&#xff0c;使得我…

前端基础篇-前端工程化 Vue 项目开发流程(环境准备、Element 组件库、Vue 路由、项目打包部署)

&#x1f525;博客主页&#xff1a; 【小扳_-CSDN博客】 ❤感谢大家点赞&#x1f44d;收藏⭐评论✍ 文章目录 1.0 环境准备 1.1 安装 NodeJs 1.2 验证 NodeJs 环境变量 1.3 配置 npm 的全局安装路径 1.4 切换 npm 的淘宝镜像( npm 使用国内淘宝镜像的方法(最新) ) 1.5 查看镜像…

QGIS编译(跨平台编译)056:PDAL编译(Windows、Linux、MacOS环境下编译)

点击查看专栏目录 文章目录 1、PDAL介绍2、PDAL下载3、Windows下编译4、linux下编译5、MacOS下编译1、PDAL介绍 PDAL(Point Data Abstraction Library)是一个开源的地理空间数据处理库,它专注于点云数据的获取、处理和分析。PDAL 提供了丰富的工具和库,用于处理激光扫描仪、…

Winform数据绑定

简介# 在C#中提起控件绑定数据&#xff0c;大部分人首先想到的是WPF&#xff0c;其实Winform也支持控件和数据的绑定。 Winform中的数据绑定按控件类型可以分为以下几种&#xff1a; 简单控件绑定列表控件绑定表格控件绑定 绑定基类# 绑定数据类必须实现INotifyPropertyChanged…

Docker 安装 Nginx 容器,反向代理

Docker官方镜像https://hub.docker.com/ 寻找Nginx镜像 下载Nginx镜像 docker pull nginx #下载最新版Nginx镜像 (其实此命令就等同于 : docker pull nginx:latest ) docker pull nginx:xxx #下载指定版本的Nginx镜像 (xxx指具体版本号)检查当前所有Docker下载的镜像 docker…

Linux 创建交换空间

&#x1f680; 作者主页&#xff1a; 有来技术 &#x1f525; 开源项目&#xff1a; youlai-mall &#x1f343; vue3-element-admin &#x1f343; youlai-boot &#x1f33a; 仓库主页&#xff1a; Gitee &#x1f4ab; Github &#x1f4ab; GitCode &#x1f496; 欢迎点赞…