程序设计实训题3
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
基础实训21
5. 分解质因数
整数分解质因数是最基本的分解。例如,90=2*3*3*5, 1960=2^3*5*7^2,前者为质因数乘积形式,后者为质因数的指数形式。
把指定区间上的所有整数分解质因数,•每一整数表示为质因数从小到大顺序的乘积形式。如果被分解的数本身是素数,则注明为素数。
例如, 92=2*2*23, 91(素数!)。
分解:
1671861=
5845271=
(1)设计要点
对每一个被分解的整数i,赋值给b(以保持判别运算过程中i不变),用k(从2开始递增取值)试商:
若不能整除,说明该数k不是b的因数,k增1后继续试商。
若能整除,说明该数k是b的因数,打印输出"k*";b除以k的商赋给b(b=b/k)•后继续用k试商(注意,可能有多个k因数),直至不能整除,k增1后继续试商。
按上述从小至大试商确定的因数显然为质因数。
循环取值k的终值如何确定,一定程度上决定了程序的效率。终值定为i-1或i/2,无效循环太多。循环终值定为i的平方根sqrt(i)可大大精简试商次数,此时如果有大于sqrt(i)的因数(至多一个!)•,在试商循环结束后要注意补上,不要遗失。
如果整个试商后b的值没有任何缩减,仍为原待分解数i,说明i是素数,作素数说明标记。
(2)质因数分解乘积形式程序设计
// 质因数分解乘积形式
#include"math.h"
#include
void main()
{long int b,i,k,m,n,w=0;
printf("[m,n]中整数分解质因数(乘积形式).\n");
printf("请输入m,n:");
scanf("%ld,%ld",&m,&n);
for(i=m;i<=n;i++) // i为待分解的整数
{ printf("%ld=",i);
b=i;k=2;
while(k<=sqrt(i)) // k为试商因数
{if(b%k==0)
{b=b/k;
if(b>1)
{printf("%ld*",k);
continue; // k为质因数,返回再试
}
if(b==1) printf("%ld\n",k);
}
k++;
}
if(b>1 && b
printf("%ld\n",b); // 输出大于i平方根的因数
if(b==i)
{printf("(素数!)\n");w++;} // b=i,表示i无质因数
}
printf("其中共%d个素数.\n",w);
}
1671861=3*31*17977
5845271=233*25087
6. 构建横竖折对称方阵
试观察图所示的横竖折对称方阵的构造特点,总结归纳其构造规律,设计并输出n(奇数)阶对称方阵。
图 7阶横竖对称方阵
输出15阶、19阶横竖折对称方阵。
解: 这是一道培养与锻炼观察能力、归纳能力与设计能力的有趣案例。
设置2维数组a[n][n]存储n阶方阵的元素,数组a[n][n]就是数据结构。本案例求解算法主要是给a数组赋值与输出。一个一个元素赋值显然行不通,必须根据方阵的构造特点,归纳其构建规律,分区域给各元素赋值。
(1)构造规律与赋值要点
观察横竖折对称方阵的构造特点,方阵横向与纵向正中有一对称轴。两对称轴所分4个小矩形区域表现为同数字横竖折递减,至4顶角元素为1。
设阶数n(奇数)从键盘输入,对称轴为m=(n+1)/2。
设置2维a数组存储方阵中元素,行号为i,列号为j,a[i][j]为第i行第j列元素。
可知主对角线(从左上至右下)有:i=j;
次对角线(从右上至左下)有:i+j=n+1。
按两条对角线把方阵分成上部、左部、右部与下部4个区,如图所示。
图对角线分成的4个区
对角线上元素可归纳到上、下部,即上、下部区域带等号即可。
上、下部按列号j的函数abs(m-j)赋值:
if(i+j<=n+1 && i<=j || i+j>=n+1 && i>=j)
a[i][j]=abs(m-j);
左、右部按行号i的函数abs(m-i)赋值:
if(i+j a[i][j]=abs(m-i); 输出时,按a[i][j]打印。 (2)程序设计 // 横竖折对称方阵 #include #include void main() {int i,j,m,n,a[30][30]; // 定义数据结构 printf(" 请确定方阵阶数(奇数)n: "); scanf("%d",&n); if(n%2==0) {printf(" 请输入奇数!");return;} m=(n+1)/2; for(i=1;i<=n;i++) for(j=1;j<=n;j++) { if(i+j<=n+1 && i<=j || i+j>=n+1 && i>=j) a[i][j]=abs(m-j); // 方阵上、下部元素赋值 if(i+j a[i][j]=abs(m-i); // 方阵左、右部元素赋值 } printf(" %d阶对称方阵为:\n",n); for(i=1;i<=n;i++) { for(j=1;j<=n;j++) // 输出对称方阵 printf("%3d",a[i][j]); printf("\n"); } }