第 3 章 数式精彩纷呈 数式是由数字、运算符与等号构成的等式。如果说单纯的数或略显单调,那么数式则 丰满得多! 广阔得多! 有趣得多! 本章探求并发掘各类新颖奇妙的数式,与诸位一道领略数学殿堂上数式的风采。 在整数素因数分解式的基础上,探索涉及分数的埃及分数式与桥本分数式;探讨涉及 整数的优美和式、平方式、变序数和式与倍积式;探求优美隐序四则运算式与含乘方^ 的 综合运算式。 重点探索与发掘从乘积、四则运算到综合运算的系列对称运算式,感受奇特而优雅的 对称美;最后分段和幂式,是对卡普雷卡数广度的拓展与深层次的发掘,回味无穷。 数式精彩,精彩数式! 数式精彩,有待我们去欣赏,欣赏数式精彩所集聚的数学美。 精彩数式,有待我们去发掘,发掘人类尚未开发的数式瑰宝。 3.1 素因数分解式 整数分解素因数(又称分解质因数)是整数分解中最基本的案例。 分解一个整数的素因数并不轻松,甚至是一项艰难繁复的工作。但分解素因数是趣 味数学的基础,众多趣味数学问题的求解往往离不开整数的素因数分解。 当整数的素因数不太大时,整数的素因数分解并不棘手。例如,分解2016,其分解的 素因数可写成以下乘积式与指数式: 2016=2×2×2×2×2×3×3×7 2016=25×32×7 当分解整数的素因数比较大时,素因数分解如何实施? 本节在寻求分解基础上,编程拓展按指数形式的分解设计,把分解的结果表示为素因 数的指数式。 【问题】 对整数n=201804分解素因数,所分解的素因数按从小到大写为乘积式。 【思考】 从2,3开始,通过试商逐个找出素因数。 (1)分解思路。 首先求出小于或等于[n ](整数n 开平方取整)的所有素数。 注意到[201804]=449,小于或等于449的素数有2,3,5,7,…,449,共计87个,理 论上这87 个素数都可能成为201804 的素因数。 首先分解出201804 的所有2因数,直到变为奇数;然后对余下奇数分解出201804 的 所有3因数;再对余下奇数依次分解所有5因数、7因数…… 直到分解449 因数。 (2)按以上思路分解操作。 ①分解201804 的2因数:201804/2=100902,100902/2=50451,可得2个2因数。 ②分解奇数50451 的3因数:50451/3=16817,16817 不能被3整除,可得1个3 因数。 ③对余下数16817 通过试商5,7,61 等,没有这些因数。 11,…, ④对余下数16817 通过试商分解67 因数:16817/67=251,可得1个67 因数。 ⑤判断251 为素数,即251 为素因数。 (3)写出素因数分解式。 于是得到201804 素因数分解式: 201804=2×2×3×67×251 因[201804]=449,原则上要试商小于或等于449 的所有素数,可见试商分解的工 作量是比较大的。本问题由于已得251 为素因数,因此结束对201804 的素因数分解。 【编程拓展】对给定的正整数 n 分解素因数,表示为素因数从小到大顺序的指数 形式。如 果被分解的整数本身是素数,则注明为素数。 1. 设计要点 为了扩展分解整数的范围,程序设计采用双精度型变量。 首先赋值“b=n;,(”) 分解操作只对 b 实施,以保持操作过程中整数 n 不变。 (1)设置条件循环实施试商。 设置 k 条件循环(3,…,n)实施试商,判别 k 是否为整数 n 的因数。 k=2, 注意到整数 n 的最大因数可能为n/2,用k(2~n/2)试商是可行的,但并不是最简便 的。事实上,用k(2~n)试商可避免许多无效操作,其算法复杂度要低一些。 在 k 试商循环中,若 k 不能整除b, k 增1后继续试商。若k 说明数 k 不是 b 的因数, 能整除b,说明数 k 是 b 的因数, j++;” 同时 b 除以 k 的商赋给 b (bfor(后继续用 k 试商 用 ( “统计 k 因数的个数; 直至 k 不能整除b, =lob/k)) 注意:可能有多个 k 因数), k 增1 后继续试商。 按上述 k 从小至大试商确定的因数显然为素因数。 如果整数 n 存在大于n(即pn,5)) 至多一个), 测试商后的 b 值。 (2)检测大因数或素数。 ow(0.的因数( 在试商循环结束后的检 若b=1,素因数分解完成。 若b1时需加打指数 (^j)。这样要求程序设计进行必要的判别操作。 2. 素因数分解指数形式程序设计 //探求指定整数的素因数分解指数形式 #include #include void main() { double b,i,k,n; int j; printf(" 请输入正整数n:");scanf("%lf",&n); printf(" %.0f=",n); b=n;k=2;j=0; while(k<=pow(n,0.5)) //枚举试商因数k { if(fmod(b,k)==0) { b=floor(b/k);j++;continue; } //k 为素因数需返回再试 if(j>=1) { printf("%.0f",k); if(j>1) printf("^%d",j); //打印素因数指数形式 if(b>1) printf("×"); } k++;j=0; } if(b>1 && b200,不符合要求。 取a=16,代入得b=144<200,符合要求,得埃及分数的两个分母为16,144 。 75 76 取a=17,代入得b 为非整数,不符合要求。 取a=18,代入得b=72,与原分母相同,不符合要求。 取a=17~23,代入得b 为非整数,不符合要求。 取a=24,代入得b=36<200,符合要求,得埃及分数的两个分母为24,36。 取a=25~27,代入得b 为非整数,不符合要求。 (3)写出埃及分数式。 因而,得到满足要求a,b(a void main() { int a1,a2,a,b,c,d,m,n,z; long x,y; printf(" 确定分数m/d,请输入m,d:"); scanf("%d,%d",&m,&d); printf(" 请确定分母的上界: "); scanf("%d",&z); n=0; 77 a1=d*z/(m*z-2*d); a2=d*3/m+1; for(a=a1;a<=a2;a++) //建立三重循环枚举 for(b=a+1;b<=z-1;b++) for(c=b+1;c<=z;c++) { x=m*a*b*c; y=d*(a*b+b*c+c*a); //计算x,y 值 if(x==y && b!=d && c!=d) //满足条件时输出分解式 { printf(" NO%d: %d/%d=1/%d",++n,m,d,a); printf("+1/%d+1/%d \n",b,c); break; } }p rintf(" 共以上%d 个分解式。\n",n); } (3)程序运行示例与说明。 确定分数m/d,请输入m,d: 5,121 请确定分母的上界: 1100 NO1: 5/121=1/27+1/297+1/1089 NO2: 5/121=1/33+1/99+1/1089 NO3: 5/121=1/45+1/55+1/1089 共以上3 个分解式。 通过程序设计探索得到:分解5/121为3个埃及分数之和,最大分母最小为1089,即 不可能有比上述3个分解式更优的分解。 结果中的最后一个分解式是程序设计得到的新的最优分解式。 注意:确定分母的上界大小直接关系所分解的埃及分数式解。例如,以上对5/121 的分解,若输入上界为1000,则没有分解式;若输入上界为3000,则存在7个分解式。 3.3 桥本分数式 数学家桥本吉彦教授于1993年在我国山东举行的中日美三国数学教育研讨会上向 与会者提出以下填数趣题:把1,2,…,9这9个数字不重复填入下式的9个方格□中,使 下面的分数式成立。 □ □□+ □ □□= □ □□ 桥本吉彦教授当即给出了一个解答。 【问题】 试探求这一分数式填数趣题的填数结果。 【思考】 以某一简单分数式为基础,每个分数分子、分母同时扩大以寻求数字不 重复。可 采用在某一简单分数和式的基础上,试验把每一分数的分子、分母同时扩大或缩 小,以寻求在式中出现1~9这9个数字而不重复的目标。 78 (1)以简单分数式1/14+1/14=1/7为基础。 前一分数1/14的分子、分母同时扩大4倍得4/56; 后一分数1/14的分子、分母同时扩大7倍得7/98; 右边分数1/7的分子、分母同时扩大3倍得3/21。 3个分数实现数字1~9各出现一次不重复,因而得到一个解:4/56+7/98=3/21。 (2)以简单分数式9/51+8/51=1/3为基础。 前一分数9/51的分子、分母同时乘以2/3倍得6/34; 后一分数8/51保持不变; 右边分数1/3的分子、分母同时扩大9倍得9/27。 3个分数实现数字1~9各出现一次不重复,因而又得到一个解:6/34+8/51=9/27。 采用以上方法试探,可省略对分数式相等的检测,减少计算量。但带有一定的盲目 性,要想试探出所有解是困难的。 要求解桥本分数式的所有解,有必要借助程序设计进行全面搜索。 【编程拓展】 桥本分数式这一9数字填数趣题究竟有多少个不同的解(约定式左边两个分数中分 子小的在前)? 同时,原题并没有要求3个分数为最简分数(即分子、分母没有大于1的公因数),如 果要求式中3个分数都为最简分数,又有多少个不同的解? 1. 设计要点 设分数式为b1/b2+c1/c2=d1/d2,注意到等式左边两个分数交换次序只算一个解 答,因而约定b1 void main() { int b1,b2,c1,c2,d1,d2,j,n,t,x,f[11]; char ch; printf(" 如果要求各分数都为最简分数,请输入字符y:"); ch=getchar(); 79 n=0; for(b1=1;b1<=8;b1++) for(c1=b1+1;c1<=9;c1++) //确保c1>b1 for(d1=1;d1<=9;d1++) for(b2=12;b2<=97;b2++) //枚举3 个分数的分子、分母 for(c2=12;c2<=98;c2++) for(d2=12;d2<=98;d2++) { if(b1*c2*d2+c1*b2*d2!=d1*b2*c2) continue; //若分数式不成立则返回 for(x=0;x<=9;x++) f[x]=0; f[b1]++;f[c1]++;f[d1]++; f[b2/10]++;f[b2%10]++;f[c2/10]++; f[c2%10]++;f[d2/10]++;f[d2%10]++; //分离数字用f 数组统计 for(t=0,x=1;x<=9;x++) if(f[x]!=1) {t=1; break;} //检验数字1~9 是否有重复 if(t==0 && ch=='y') //检验是否为3 个最简分数 { for(j=2;j<=9;j++) if(b1%j==0 && b2%j==0){t=1;break;} else if(c1%j==0 && c2%j==0){t=1;break;} else if(d1%j==0 && d2%j==0){t=1;break;} }i f(t==0) //输出一个填数解 { printf("%4d: %1d/%2d+%1d/%2d",++n,b1,b2,c1,c2); printf("=%1d/%2d ",d1,d2); if(n%2==0) printf("\n"); } }p rintf("\n 共以上%d 个解。\n",n); } 3. 程序运行结果与变通 若填数不要求3个分数为最简分数,程序运行结果如下。 如果要求各分数都为最简分数,请输入字符y:n 1: 1/78+4/39=6/52 2: 1/26+5/78=4/39 3: 1/32+5/96=7/84 4: 1/32+7/96=5/48 5: 1/96+7/48=5/32 6: 2/68+9/34=5/17 7: 2/68+9/51=7/34 8: 4/56+7/98=3/21 9: 5/26+9/78=4/13 10: 6/34+8/51=9/27 共以上10 个解。 若填数要求3个分数为最简分数,则程序运行结果如下。 如果要求各分数都为最简分数,请输入字符y:y 1: 1/26+5/78=4/39 2: 1/32+7/96=5/48 3: 1/96+7/48=5/32 共以上3 个解。 程序能搜索不要求最简分数的桥本分数式,也能搜索附加条件“要求各分数都为最简 分数”的分数式,这是程序设计的特色。 变通:把0,1,2,…,9这10 个数字填入下式的10 个方格中,要求:各数字不得重复; 数字0不得填在各分数的分子或分母的首位。 □□□ += □□□□□ □ □ 这一分数式填数究竟共有多少个解 ? 3.4 优美和式与平方式 优美和式是一个创新填数趣题,其优美体现在所涉约定数字在和式中不重复,是和谐 美的具体体现。 和式分为三项和式(左边两项求和)和引申的四项和式(左边三项求和)两类,益智训 练,各具特色。 3.1 9数字优美和式 4. 因9数字优美和式涉及1~9这9个正整数,不涉及数字0,变化较为简单。 把1,2,…,9这9个数字分别填入以下和式中的9个□中,要求1~9这9个数字在 式中出现一次且只出现一次,使得和式成立。 □□□ + □□□ = □□□ (3-4-1) 【问题1】试求和式(3-4-1)中的和(即式右3位数)的最大值。 【思考】从进位次数确定式右的数字和入手。 注意到1~9这9个数字之和为45 。 (1)确定进位次数。 式左求和时每次进位,所进的1相当于10,求和结果的数字和会减少9。 例如,数式218+439=657 中,式右的数字和为18,式左的数字和为27,式右比式左 的数字和要小9,就是求和运算的一次进位8+9=17 造成的。 首先确定:和式(1)左边求和过程中有一次且只有一次进位。 事实上,若左边求和时没有进位,则式左的6个数字之和与式右的3个数字之和相 等,即都为9个数字之和45 的一半(非整数), 矛盾。 若左边求和有2次进位,使数字和减小了2×9=18,因而式右的3个数字之和为 45-2×9=27 的一半(非整数), 矛盾。 若左边求和有3次进位,则式右作为求和结果必为4位数,矛盾。 可见,和式(1)左边求和过程中有一次且只有一次进位。 (2)确定式右3位数的数字和。 和式左边求和有一次进位,因而和式右边的3个数字之和为(45-9)/2=18 。 (3)探索最大值。 根据式右3位数的3个互不相同的数字之和为18,其最大值的高位(即百位)数字尽 80 81 可能大,选择填9;十位数字也尽可能大,可填8;相应个位数字为1。 对于所填和981,需寻找相应的数字1~9没有重复数字的和式(可能存在多个),例 如和式235+746=981。 因而得和式(3-4-1)右边和的最大值为981。 【编程拓展】 和式(3-4-1)右边和的最小值为多大? 和式(3-4-1)共有多少种不同的填法? 以下应 用程序设计探求这些问题。 为避免式左两个加数交换个位数字,或交换十位数字,或交换百位数字造成多种重 复,约定式左两个加数的前一个3位数的各位数字分别小于后一个3位数的相应数字。 同时,为了便于观察右边和的最小值与最大值,约定右边的和按从小到大排列,且要 求每个和值只输出一个和式。 1. 设计要点 设3个3位数为a,b,c,和式为a+b=c。 (1)设置循环。 建立和数c 循环(315~987),这里循环初值315是百位数为3(因左边a,b 都有较小 的百位数字)且为9倍数的最小3位数;循环终值为没有重复数字的最大3位数987;循环 步长设为9,以提高搜索效率。 同时建立加数a 循环(123~c/2),因约定a void main() { int a,b,c,d,t,m,n,x,g[10]; n=0; for(c=315;c<=987;c+=9) //和c 为9倍数 for(a=123;a void main() { int a,b,c,d,t,m,n,x,g[10]; n=0; for(c=1026;c<=1987;c+=9) //1026 是能被9 整除的最小4 位数 for(a=102;a999) continue; for(x=0;x<=9;x++) g[x]=0; d=a;g[d%10]++;g[d/100]++;m=(d/10)%10;g[m]++; d=b;g[d%10]++;g[d/100]++;m=(d/10)%10;g[m]++; g[c/1000]++;d=c%1000; //统计式中各数字的频数 g[d%10]++;g[d/100]++;m=(d/10)%10;g[m]++; for(t=0,x=0;x<=9;x++) if(g[x]!=1) {t=1;break;} //检验数字0~9 各出现一次 if(t==0) { printf("%4d: %d+%d=%d",++n,a,b,c); //统计并输出一个解 if(n%3==0) printf("\n"); a=c;break; } } printf("\n 共以上%d 个10 数字三项和式。\n",n); } (3)程序运行结果与说明。 1: 437+589=1026 2: 246+789=1035 3: 264+789=1053 4: 473+589=1062 5: 324+765=1089 6: 342+756=1098 7: 347+859=1206 8: 426+879=1305 9: 624+879=1503 10: 743+859=1602 共以上10 个10 数字三项和式。 由以上运行结果输出的10个优美和式看出,和式(3-4-3)右边和的最小值为1026,最 大值为1602,与上面所解结论相同。 【引申】 把和式(3-4-3)左边的两项分解为三项,即为以下的四项和式。 □ + □□ + □□□ =□□□□ (3-4-4) 和式(3-4-4)涉及四项a+b+c=d,在以上程序基础上,增加一重循环,各参数进行 相应变通,具体修改自行完成。 优美和式(3-4-4)的解如下: 85 1: 3+45+978=1026 2: 2+46+987=1035 3: 2+64+987=1053 4: 3+74+985=1062 共以上4 个10 数字四项和式。 由以上运行结果输出的4个和式看出,和式(3-4-4)右边和的最大值为1062,最小值 为1026。 3.4.3 优美平方式 优美平方式:如果数字1~9不重复填入式(3-4-5)的9个□中使等式成立,则该等式 称为优美平方式。 □□□□□□ =(□□□)2 (3-4-5) 式(3-4-5)的左边为一个6位数,右边是一个3位数的平方。 编程构建所有优美平方式。 1. 设计要点 设置f数组存储式中各个数字的频数,便于比较是否存在重复数字。 (1)枚举循环设置。 若整数a为4位,则a2 的位数达7位,超出范围。因而整数a只能为3位。 通过循环计算最小的3位整数t,设置循环a(t+1~10t-1)枚举3位整数。 计算d=a*a,若d的位数不足6位,则a与d的位数之和小于9,因而导致数字1~9 填不下,则返回。 (2)分离整数数字并统计频数。 应用求余与取整运算分离a,d的各个数字。 在数组元素f[k](k:0~9)清零后,通过“f[k]++;”统计各数字的频数。 (3)检测重复数字。 检测整数a,d的数字频数f[k],若f[k]≠1(k:1~9),则返回。 若f[k]=1(k:1~9),满足优美要求,则输出平方式。 2. 程序设计 //探求9 数字优美平方式 #include void main() { int k,p,s,f[10]; long a,d,t,w; s=0;t=1; for(k=1;k<=2;k++) t=t*10; //t 为3 位最小整数 for(a=t+1;a<=t*10-1;a++) { d=a*a; w=d; //确保d 为平方数 if(d<100000) continue; for(k=0;k<=9;k++) f[k]=0; while(w>0) //分离d 的数字并统计频数 86 { k=w%10;f[k]++;w=w/10;} w=a; while(w>0) //分离a 的数字并统计频数 { k=w%10;f[k]++;w=w/10;} for(p=0,k=1;k<=9;k++) if(f[k]!=1) p=1; //平方式中是否有重复数字 if(p==0) printf("%d: %ld=%ld^2\n",++s,d,a); //统计个数并输出平方式 }i f(s>0) printf(" 共以上%d 个9 数字优美平方式。\n",s); else printf("\n 不存在满足要求的平方式。\n"); } 3. 程序运行示例与说明 1: 321489=567^2 2: 729316=854^2 共以上2 个9 数字优美平方式。 由以上运行结果可以看出,输出的2个优美平方式中的9个数字为1~9不重复 出现。能 否加入数字0构建10数字优美平方式呢? 回答是否定的。因为3位整数a的平 方数最多为6位,若a增加为4位,则d=a2 至少为7位,超出10位的数字范围。 3.5 优美综合运算式 本节创新构建隐序四则运算式及综合运算数学式,这是一个有趣也有难度的填数 游戏。各 数学式称为“优美”,是指各个数字在式中不重复,是和谐美的具体体现。 3.5.1 隐序四则运算式 本节所论述的数式除了含四则运算与数字不重复外,还必须符合指定隐序。这一新 增要求是新颖的,也是有趣的。 把0,1,2,…,9这10个数字不重复填入以下含加、减、乘、除(乘除运算优先于加减运 算)的四则运算式中的10个□中,使等式成立。 □□□ + □□ ÷ □ - □□ × □ =□ (3-5-1) 约定式(3-5-1)填数字时,1,0不出现在式左边的1位数中,且数字0不能为整数 首位。同 时,要求式中的10个不重复的数字须符合指定隐序,指定隐序由输入的整数决定。 例如,如果指定隐序为4位数2019,则该运算式中数字的隐含顺序:数字2须在0的左 边,数字0须在1的左边,而数字1须在9的左边(这就是隐序的含意)。 87 例如,267+80÷5-31×9=4就是一个符合2019指定隐序的优美四则运算式。 输入指定隐序的整数,构建并输出所有符合指定隐序的优美四则运算式。 1. 设计要点 (1)数据结构。 以上四则运算式中的各数依次设置为变量a,b,c,d,e,f,即四则运算式为 a+b/c-d*e=f 同时设置3个数组:g数组统计式中共6个整数的10个数字的频数,便于判别重复 数字;h数组标记式中10个数字的位置,便于判别是否符合指定隐序;w 数组存储指定隐 序,为判别是否符合指定隐序提供数据。 (2)设置枚举循环。 设置a,c,d,e,f循环,其中c,e,f都是1位数,f循环0~9取值,c,e循环2~9取值; 数a为3位数,循环102~987取值;数d为2位数,循环10~98取值。 (3)计算整数b。 把以上四则运算式变形为以下的乘积式是简便的。 b=(d*e+f-a)c 对每组a,c,d,e,f,计算b。这样处理,可省略b循环,省略b是否能被c整除,也省略 等式是否成立的检测。 计算b后,检测b是否为2位数。若计算所得b非2位数,则返回。 (4)判别是否存在重复数字。 然后分别对6个整数进行数字分离,设置g数组对6个整数分离的共10个数字进行 统计,g[x]即为数字x(0~9)的频数。同时,应用h数组标记式中10个数字的位置。 例如,g[3]=2,即为2个数字3;h[5]=4,即数字5在数式中第4个位置上。 若某一g[x]≠1,不满足10个数字都出现一次且只出现一次,标记t=1。 若所有g[x]全为1,满足10个数字都出现一次且只出现一次,保持标记t=0,则优 美四则运算式成立。 (5)判别是否符合指定隐序。 式中10个数字的分布必须符合指定顺序的要求,这既是重点,也是难点。 输入的指定隐序的整数m 要求没有重复数字,位数不限(当然不能超过10)。因此, 首先分离隐序m 的各个数字(设为n个数字),并从个位开始赋值给w[1]~w[n]。 综合h与w数组来判别所得优美四则运算式的10个数字分布是否符合指定要求。 因指定隐序的整数m 的w[k]在w[k-1]的前面,即h[w[k]]=h[w[k-1]] (k:2~n)不符合指定隐序,即返回试下一个数式。 2. 程序设计 //探求指定隐序的优美四则运算式:□□□+□□/□-□□×□=□ //式中10 个不重复的数字须符合指定隐序 #include 88 void main() { int a,b,c,d,e,f,k,t,m,n,x,y,z,g[11],h[11],w[11]; printf(" 请输入指定隐序数m(数字互不相同): "); scanf("%d",&m); n=0;y=m; while(y>0) {x=y%10;w[++n]=x;y=y/10;} //分离m 的数字赋值w 顺序数组 m=0; for(f=0;f<=9;f++) for(a=102;a<=987;a++) for(c=2;c<=9;c++) for(d=10;d<=98;d++) //循环实施枚举a,c,d,e,f for(e=2;e<=9;e++) { b=(d*e+f-a)*c; //计算变量b 省去b 循环 if(b<10 || b>99) continue; for(x=0;x<=9;x++) g[x]=0; g[c]++;g[e]++;g[f]++; //3 个1 位数给g,h 数组赋值 h[c]=6;h[e]=9;h[f]=10; y=a; for(k=1;k<=3;k++) { x=y%10;g[x]++;h[x]=4-k;y=y/10;} //分离a 的3 个数字给g,h 数组统计 g[b/10]++;h[b/10]=4;g[b%10]++;h[b%10]=5; g[d/10]++;h[d/10]=7;g[d%10]++; h[d%10]=8; //分离b,d 数字给g,h 数组统计 for(t=0,x=0;x<=9;x++) if(g[x]!=1) {t=1;break;} //检验数字0~9 是否存在重复 if(t==1) continue; for(t=0,k=n;k>=2;k--) if(h[w[k]]>=h[w[k-1]]) {t=1;break;} //检验是否符合w 数组指定隐序 if(t==1) continue; printf(" %2d:%d+%d÷%d",++m,a,b,c); printf("-%d×%d=%d",d,e,f); if(m%2==0) printf("\n"); //以每行2 个输出符合要求数式 }p rintf(" 共以上%d 个符合指定隐序的优美四则运算式!\n",m); } 3. 程序运行示例与说明 请输入指定隐序数m(数字互不相同): 2019 1:267+80÷5-31×9=4 2:204+18÷9-67×3=5 3:207+18÷9-34×6=5 4:240+16÷8-79×3=5 5:270+84÷6-31×9=5 6:720+45÷3-81×9=6 7:250+81÷9-63×4=7 8:643+20÷5-71×9=8 9:205+68÷4-71×3=9 10:208+56÷4-71×3=9 11:237+80÷5-61×4=9 12:250+81÷3-67×4=9 共以上12 个符合指定隐序的优美四则运算式! 89 从运行结果中清楚可见,每个式中的10个数字无重复,且其分布隐含指定2019顺 序。式中含加、减、乘、除的四则运算,运算结果使等式成立。 若输入的指定隐序数m 为20195,则只有以上第2,3,4,5个解满足要求。 若输入的指定隐序数m 为20197,则只有以上第2,7个解满足要求。 这里特别强调,输入隐序数m 时,不能含有重复数字,否则,程序难以进行测试。 3.5.2 综合运算式 【问题】 在以下数式(3-5-2)中已填有数字0,4,6,把另7个数字1,2,3,5,7,8,9不 重复填入以下含加、减、乘、除与乘方的综合运算式中的7个□中,使得该式成立。 46 + □□ ÷ □ - □□□ × □ =0 (3-5-2) 约定数字1不出现在数式的1位数中。 【思考】 把式中乘积项设置在大于乘方数值附近探试。 式中10个数字已填有3个,是为了减少填数字的难度。 设式(3-5-2)中的2位数为x。 注意到已有46=4096=512×8,因而拟把□□□×□设置在大于512×8附近,分以 下情形讨论。 (1)取46+□□÷□-512×9=0,则□□÷□=512,不可能实现。 (2)取46+□□÷□-513×8=0,则□□÷□=8,即2位数x 为8的倍数。 x=16,24,32,40,48,56,64与80,分别导致数字6,4,3,4,4,6,4,8矛盾。 而对于x=72,有72÷9=8,则可得综合运算式 46 +72÷9-513×8=0 (3-5-3) 即得对应式(3-5-2)的综合运算式(3-5-3)。 【编程拓展】 把0,1,2,…,9这10个数字不重复填入以下含加、减、乘、除与乘方的 综合运算式中的10个□中,使得该式成立。 □□ + □□ ÷ □ - □□□ × □ =□ 约定数字1,0不出现在式左边的1位数中,且0不能为整数首位。试探索并输出所 有综合运算式。 1. 设计要点 设综合运算式为 a^b+z/c-d*e=f 把所有变量设置为整型,其中乘方a^b用a自乘b次实现。 (1)设置枚举循环。 设置a,b,c,d,e,f循环,其中a,b,c,e,f都是1位数,f循环为0~9取值,而a,b,c,e 循环为2~9取值;数d为3位数,循环为102~987。 (2)计算数z。 对每组a,b,c,d,e,f,计算 z=(d*e+f-a^b)*c 这样设计,可省略z循环,省略z是否能被c整除,省略等式是否成立的检测。 90 计算z后,检测z是否为2位数。若计算所得z非2位数,则返回。 (3)判别是否存在重复数字。 然后分别对7个整数进行数字分离,设置g数组对7个整数分离的共10个数字进行 统计,g[x]即为数字x(0~9)的频数。 若某一g[x]不为1,不满足10个数字都出现一次且只出现一次,标记t=1。 若所有g[x]全为1,满足10个数字都出现一次且只出现一次,保持标记t=0,则输 出所得的优美综合运算式。 2. 程序设计 //探求完美综合运算式:□^□+□□/□-□□□*□=□ //式左的1 位数不能为0 或1, 式左的整数首位不能为0 #include void main() { int a,b,c,d,e,f,k,t,n,x,y,z,g[11]; n=0; for(f=0;f<=9;f++) for(a=2;a<=9;a++) for(b=2;b<=9;b++) for(c=2;c<=9;c++) for(d=102;d<=987;d++) //各数实施枚举 for(e=2;e<=9;e++) { for(t=1,k=1;k<=b;k++) t=t*a; //计算乘方a^b z=(d*e+f-t)*c; if(z<10 || z>98) continue; //计算z,若z 非2 位数则返回 for(x=0;x<=9;x++) g[x]=0; g[f]++;g[a]++;g[b]++;g[c]++;g[e]++; //5 个1 位数给g 数组赋值 y=d; for(k=1;k<=3;k++) { x=y%10;g[x]++;y=y/10;} //分离d 的3 个数字给g 数组统计 g[z/10]++;g[z%10]++; //分离z 的2 个数字给g 数组统计 for(t=0,x=0;x<=9;x++) if(g[x]!=1) {t=1;break;} //检验数字0~9 是否各出现一次 if(t==0) //输出一个解 { printf(" %2d:%d^%d+%d÷%d",++n,a,b,z,c); printf("-%d×%d=%d ",d,e,f); if(n%2==0) printf("\n"); } }p rintf(" 共以上%d 个完美综合运算式!\n",n); } 91 3. 程序运行示例与变通 1:4^6+72÷9-513×8=0 2:5^4+78÷6-319×2=0 3:9^3+48÷6-105×7=2 4:9^3+64÷8-105×7=2 5:2^9+78÷6-130×4=5 6:9^3+64÷2-108×7=5 7:2^9+80÷5-174×3=6 8:5^4+18÷9-207×3=6 9:9^3+50÷2-187×4=6 10:5^4+96÷8-210×3=7 11:6^3+54÷9-107×2=8 12:8^3+64÷2-107×5=9 共以上12 个完美综合运算式! 由以上运行结果看出,输出12个完美综合运算式,式中不重复含有0~9这10个数 字,设置有加、减、乘、除与乘方五则运算,优雅地展示出数式之美。 以上设计中应用a自乘b次实现a^b,这样处理是简便的。同时,应用g数组进行数 字统计检验是否存在有重复数字,检测手段颇为新颖。 变通:把0,1,2,…,9这10个数字分别填入以下含加、减、乘、除与乘方的综合运算 式中的10个□中(约定0,1要求同前),修改以上程序,使得下式成立。 □□ + □□□ ÷ □ - □□ × □ =□ □□ + □□ ÷ □ - □□ × □ =□□ 请问:上述综合运算式共有多少种不同的填入方法? 3.6 变序数和式 变序数是由同一组数字通过不同排列所得的位数相同的整数。 例如,由1,0,2,2这4个数字通过不同排列组成的4位整数1022,1202,1220,2012, 2021,2102,2120,2201,2210都是变序数,也称同基因数。而0122实际上只是一个3位 数,并不含0,不属于上述诸数的变序数范畴。 本节探索构建涉及变序数的新颖数式———变序数和式。 例如,2385+2853=5238就是一个4位变序数和式,式中3个4位数都是由数字2, 3,5,8通过不同排列生成,是变序数关系。 先看一个简单的3位变序数和式填数题。 【问题】 在1~9这9个数字中选择3个不同的数字,把所选的3个数字以某种不同 顺序分别填入以下和式中的3个3位数中,使和式成立。 □□□+□□□=□□□ 也就是说,式中3个3位数的组成数字是相同的,只是排列顺序不同,这3个3位数 是变序数关系。 共有多少个不同的3位变序数和式(约定式中第1个3位数小于第2个3位数)。 【思考】 从进位次数确定式右3位数的数字和入手。 因为和式中的3个3位数是由同样数字经不同排列组成的,所以式左的数字之和为 式右的数字和的2倍。 (1)确定进位次数与式右数字和。