“幸运方阵”问题分析 向右看齐 2022-08-13 00:54 138阅读 0赞 ## 1.问题描述 ## 幸运方阵问题:任意指定一个阶数,例如3,在任意选定一个“幸运数”,例如100,要求生成一个3阶方阵。从方阵中任意划去一行与一列,记下交叉点的数值;再从方阵剩余部分划去一行与一列,在记下交叉点数值;继续这一过程,当方阵已不剩下任何元素时,所有记下的值之和恰好为100。 <table> <tbody> <tr> <td>12</td> <td>13</td> <td>68</td> </tr> <tr> <td>14</td> <td>15</td> <td>70</td> </tr> <tr> <td>17</td> <td>18</td> <td>73</td> </tr> </tbody> </table> 如左图所示,任意不同行不同列的3个数之和均为100。目标就是为了生成指定阶数n和幸运数num的方阵。 ## 2.算法分析 ## 如果采用先生成随机数然后用递归的计算和是否为幸运数的方法来处理这个问题,过程会非常繁琐而且算法效率低下。那么我们可以考虑,方阵是n\*n型的,我们可以用两个数组行数组row和列数组col各存放n个数,行数组和列数组中的数两两相加,一共可以得到n\*n个数,分别是我们需要生成的方阵的每个元素的值。 由于要求方阵n个不同行不同列的元素值的和为幸运数num,方阵n个不同行不同列的元素值之和恰好是行数组和列数组所有元素之和,由上述思路,我们只需让行数组row和列数组col中所有数的和为幸运数num即可。具体实现可以这样做,让列数组最后一个数为num减去其余n+(n-1)个数之和。 ## 3.问题解决 ## 由上述算法分析可以编写代码如下: #include "stdafx.h" #include "stdlib.h" #include "time.h" #define SIZE 10 int _tmain(int argc, _TCHAR* argv[]) { int square[SIZE][SIZE],row[SIZE],col[SIZE],n,num,k,sum,i,j; printf("\n请输入幸运方阵的阶数: \n"); scanf("%d",&n); printf("请输入一个幸运数字: \n"); scanf("%d",&num); //srand(0); srand(time(0)); //srand放在循环外可以保证每次运行都可以得到不同的结果,增强随机性 k=num/(2*n); //当取k=num/n时方阵元素值有可能会出现负数值 if(k==0) { printf("\n你输入的幸运数字太小了,请重新输入:\n"); scanf("%d",&num); } sum=0; for(i=0;i<n;i++) { row[i]=rand()%k; col[i]=rand()%k; sum=sum+row[i]+col[i]; } col[n-1]=col[n-1]-(sum-num); //列数组最后一个值等于num减去行数组n个数和列数组前n-1个数之和 printf("\n"); for(i=0;i<n;i++) { for(j=0;j<n;j++) { square[i][j]=row[i]+col[j]; printf("%5d",square[i][j]); } printf("\n"); } return 0; } 运行结果如下: ![Image 1][] 由结果可知生成方阵任意3个不同行不同列的数之和确实为100。当我们改变阶数和幸运数的时候结果也符合要求。如下: ![Image 1][] 我们可以发现生成方阵最后一列的数普遍偏大,这是因为算法中行数组n个数和列数组中前n-1个数的值都太小,这是由k=num/(2\*n)和rand()%k决定的,而列数组最后一个数等于num减去n+(n-1)个数之和,因此偏大。 ## 4.优化思考 ## 为了方阵中每个元素值更均匀,那能不能把k=num/(2\*n)改成k=num/n呢? 经分析,确实这样生成方阵中每个数的值大小较为均匀,但是带来的问题是这样有可能生成矩阵中会产生负数。下面将n设置为固定数3,幸运数固定为100,循环产生合乎要求的方阵,从而找到包含负数的方阵的情况。代码如下: #include "stdafx.h" #include "stdlib.h" #include "time.h" #define SIZE 10 int _tmain(int argc, _TCHAR* argv[]) { int t=1; do { int square[SIZE][SIZE],row[SIZE],col[SIZE],n,num,k,sum,i,j; /* printf("\n请输入幸运方阵的阶数: \n"); scanf("%d",&n); printf("请输入一个幸运数字: \n"); scanf("%d",&num); */ n=3; num=100; //srand(0); srand(time(0)); k=num/n; if(k==0) { printf("\n你输入的幸运数字太小了,请重新输入:\n"); scanf("%d",&num); } sum=0; for(i=0;i<n;i++) { row[i]=rand()%k; col[i]=rand()%k; sum=sum+row[i]+col[i]; } col[n-1]=col[n-1]-(sum-num); printf("\n"); for(i=0;i<n;i++) { for(j=0;j<n;j++) { square[i][j]=row[i]+col[j]; printf("%5d",square[i][j]); if(square[i][j]<0) t=0; else t=1; } printf("\n"); } }while(t); return 0; } 运行结果如下: ![Image 1][] 由此可见确实产生了负数。 ## 参考来源:P127~128《C语言程序设计》,杨建霑、汪同庆主编,武汉大学出版社。 ## [Image 1]:
相关 旋转方阵 ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L1NpbW9u 旧城等待,/ 2023年07月15日 12:48/ 0 赞/ 140 阅读
相关 ZZULIOJ 1056 幸运数字问题 题目描述 小明对某些数字有偏爱,例如,他喜欢7的倍数,而不喜欢4的倍数,如果一个整数是7的倍数,而不是4的倍数,小明会认为这个数字是他的幸运数字。现在给定两个整数m和n, 古城微笑少年丶/ 2023年06月10日 06:22/ 0 赞/ 43 阅读
相关 螺旋方阵 所谓“螺旋方阵”,是指对任意给定的NNN,将1到N×NN\\times NN×N的数字从左上角第1个格子开始,按顺时针螺旋方向顺序填入N×NN\\times NN×N的方阵里。 骑猪看日落/ 2022年09月27日 06:18/ 0 赞/ 294 阅读
相关 “幸运方阵”问题分析 1.问题描述 幸运方阵问题:任意指定一个阶数,例如3,在任意选定一个“幸运数”,例如100,要求生成一个3阶方阵。从方阵中任意划去一行与一列,记下交叉点的数值;再从方阵 向右看齐/ 2022年08月13日 00:54/ 0 赞/ 139 阅读
相关 转方阵 对一个方阵转置,就是把原来的行号变列号,原来的列号变行号 例如,如下的方阵: 1 2 3 4 5 6 7 8 浅浅的花香味﹌/ 2022年08月08日 13:59/ 0 赞/ 193 阅读
相关 转方阵 对一个方阵转置,就是把原来的行号变列号,原来的列号变行号 例如,如下的方阵: 1 2 3 4 5 6 7 8 9 10 11 待我称王封你为后i/ 2022年08月02日 07:20/ 0 赞/ 182 阅读
相关 螺旋方阵 螺旋方阵 Time Limit: 1000MS Memory Limit: 65536KB [Submit][] [ Statistic][S ゝ一纸荒年。/ 2022年07月03日 14:58/ 0 赞/ 230 阅读
相关 螺旋方阵 Problem Description n×n的螺旋方阵当n=5和n=3时分别是如下的形式 ![1295.png][] 请给出一个程序,对于任意的输入n(0 墨蓝/ 2022年06月17日 05:28/ 0 赞/ 241 阅读
相关 螺旋方阵 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 所谓“螺旋方阵”,是指对任意给定的N,将1到N\N的 左手的ㄟ右手/ 2022年05月29日 05:25/ 0 赞/ 272 阅读
相关 方阵相乘 一 代码 package Matrix; / Copyright (C), 2020-2020, XXX有限公司 FileNam 约定不等于承诺〃/ 2021年07月24日 16:15/ 0 赞/ 357 阅读
还没有评论,来说两句吧...