问题 问答题

[说明] 本程序在3×3方格中填入1到10以内9个互不相等的整数,使所有相邻两个方格内的两个整数之和为质数。程序的输出是全部满足条件的方格。 方格的序号如下图所示。程序采用试探法,从序号为0的方格开始,依次为当前方格寻找一个合理的可填整数,并在当前位置正确填入后,为下一方格寻找可填入的合理整数;如不能为当前方格寻找一个合理的可填整数,就要后退到前一方格,调整前一方格的填入整数;当序号为8的方格也填入合理的整数后,就找到了一个解。

为检查当前方格所填整数的合理性,程序引入数组CheckMatrix,存放需要进行合理性检查的相邻方格的序号。事实上,CheckMatrix中只要求第i个方格中的数向前兼容,即填写第4个方格时,只检查在它之前、与之相邻的第1,3个方格是否满足和为素数的条件。[程序]#include <stdio.h>int pos,a[9],b[11]; /*用于存储方格所填入的整数*/void write(int a[]) /*方格输出函数*/{ ……}int isPrime(int m) /*素数判断函数,若m为素数则返回1,否则返回0*/{ ……}int selectNum(int start) /*找到start到10之间尚未使用过的最小的数,若没有则返回0*/{ int j; for(j=start;j<=10;j++) if(b[j]) return j; return0;}int check()/*检查填入pos位置的整数是否合理*/{ int i,j int checkMatrix[][3]={{-1},{0,-1},{1,-1},{0,-1},{1,3,-1},{2,4,-1},{3,- 1},{4,6,-1},{5,7,-1}}; for(i=0;(j= (1) )>=0;i++)if(! isPrime( (2) ))return 0; return 1;}void extend() /*为下一方格找一个尚未使用过的整数*/{ (3) =selectNum(1); b[a[pos]]=0;}void change() /*为当前方格找下一个尚未使用过的整数,若找不到则回溯*/{ int j; while(pos>=0&&(j=selectNum(a[pos]+1))= =0) b[a[pos- -]]=1; if(pos<0)return; (4) ;a[pos] =j;b[j]=0; }void find(){ int ok=1; pos=0;a[pos]=1;b[a[pos]]=0; do{ if(ok)if( (5) ){ write(a);change();}else extend(); else change(); ok=check(pos); }while(pos>=0);}void main(){ int i; for(i=1;i<=10;i++)b[i]=1; find();}

答案

参考答案:

解析:(1) checkMatrix[pos][i] (2) a[pos]+a[j] (3) a[++pos] (4) b[a[pos]]=1(5) pos= =8或pos>=8或pos>7[考点分析] 考查C语言程序设计,主要是试探和回溯算法。 程序中主要变量及其作用说明如下:pos用于标记当前要填数的方格序号;数组元素a[i]表示第i个方格所填的内容;数组元素b[j]标记整数j是否被使用 (初始化时设为1,表示没有使用);一维数组checkMatrix[i]记录了填写第i个方格需要检查的方格序号,例如checkMatrix[4]={1,3,-1},其中-1用作结束标记。(1)此循环遍历一维数组checkMatrix[pos],取出第i个数checkMatrix[pos][i]赋给j,直至-1;(2)j是checkMatrix[pos]中不等于-1的值,即表示需要检查当前方格(第pos个)与第j个的和是否是素数;(3)这条语句应包含pos增1以及a[pos]=selectNum (1)前后两个操作,因此需用++pos;(4)若能为当前方格找到下一个未被使用的数,则应先释放当前格中的数,再填入新数;(5)这条语句包含输出方格操作,因此判断的条件是全部方格被填满,即pos值已增至8。

单项选择题
选择题