自考

各地资讯
当前位置:华课网校 >> 自考 >> 模拟试题 >> 工学类 >> C语言程序设计 >> 文章内容

排行热点

自学考试《C语言程序设计》随堂试题及答案_第3页

来源:华课网校  [2017年1月31日]  【

  【4.76】参考答案:

  #include "stdio.h"

  int a[20],b[20];

  main()

  { int t=0,*m,*n,*k,*j,z,i=0;

  printf("Input number 1:");

  do

  { a[++t]=getchar()-'0';

  }while(a[t]!=-38);

  printf("Input number 2:");

  do

  { b[++i]=getchar()-'0';

  }while(b[i]!=-38);

  if(t>i)

  { m=a+t;n=b+i;j=a;k=b;z=i;

  }

  else

  { m=b+i;n=a+t;j=b;k=a;z=t;

  }

  while(m!=j)

  { (*(--n-1))+=(*(--m)+*n)/10;

  *m=(*m+*n)%10;

  if(n==k+1 && *k!=1 ) break;

  if(n==k+1 && *k)

  { n+=19;*(n-1)=1;

  }

  if(n>k+z && *(n-1)!=1) break;

  }

  while(*(j++)!=-38) printf("%d",*(j-1));

  printf("\n");

  }

  【4.77】参考答案:

  #include "stdio.h"

  int a[20],b[20],c[40];

  main()

  { int t=0,*m,*n,*k,f,e=0,*j,i=0;

  printf("Input number 1:");

  do

  { a[++t]=getchar()-'0';

  }while(a[t]!=-38);

  printf("Input number 2:");

  do

  { b[++i]=getchar()-'0';

  }while(b[i]!=-38);

  j=c;

  for(m=a+t-1;m>=a+1;m--,e++)

  { j=c+e;

  for(n=b+i-1;n>=b+1;n--)

  { f=*j+*m * *n;

  *(j++)=f%10;

  *j+=f/10;

  }

  }

  while(j>=c) printf("%d",*(j--)) ;

  printf("\n");

  }

  【4.78】这是一个使用数组解决较复杂问题的典型题目。

  棋盘如左图所示,图中箭头表示一个棋子从[1、1]点跳到[2、3]点。为了下面叙述的方便,将I、J表示棋子起跳点的行、列号,X、Y表示落子点的行、列号。

  首先我们讨论如何从起跳点坐标求出可能的落子点的坐标。

  从某点起跳,棋子最多可能有八个落子点,例如从I=3、J=5点起跳,八个可能的落子点的坐标是[4、5]、[5、4]、[5、2]、[4、1]、[2、1]、[1、2]、[1、4]、[2、5]。将起落点的行列坐标分开考虑,则由起点的行坐标分别与下列八个数相加,就可得到可能的八个落子点的行坐标:1、2、2、1、-1、-2、-2、-1,将这八个数存入数组b,即:

  b[]={1,2,2,1,-1,-2,-2,-1},

  落子点的行坐标X和起跳点行坐标有如下关系:

  X=b[k]+I 1≤k≤8

  如果由上式计算得到的落子点X的坐标值小于0或大于8,则表示落在了棋盘之外,应予舍弃。

  同理得到起落点之间的列坐标关系数组是:

  d[]={2,1,-1,-2,-2,-1,1,2}。

  我们再讨论落子点的度数问题。对于棋盘中的某一点来说,周围最多有8个方向的棋子在这个点落子,把可能的落子数称为度数,棋盘上各点的度数如下图所示。

  根据题意,一个点只能落子一次,所以落过子的点的度数应记为0,可跳向度数为0点的度数相应要减1。

  根据上述数组,从一个起跳点出发,可能求出数个可以落子点的坐标,跳棋时到底确定落在这些点中的哪一个呢?我们确定一个原则是落在度数最少的点。如果可能落子点中有两个点的度数一样且都为是度数最少时,取后求出的点为落子点。因此,如果改变数组b、d中数的存放顺序,遇到两个度数最少点的先后顺序就要改变,整个跳棋路径就可改变。 2 3 4 4 4 4 3 2

  3 4 6 6 6 6 4 3

  4 6 8 8 8 8 6 4

  4 6 8 8 8 8 6 4

  4 6 8 8 8 8 6 4

  4 6 8 8 8 8 6 4

  3 4 6 6 6 6 4 3

  2 3 4 4 4 4 3 2

  在下面的程序中,将起落子行列关系的两个一维数组合并为一个二维数组,为了提高程序的可读性,不使用下标为0的数组元素。

  参考程序:

  int base[9][3]={0, 0, 0, /* 从起跳点求落脚点的基础系数数组 */

  0, 1, 2,

  0, 2, 1,

  0, 2,-1,

  0, 1,-2,

  0,-1,-2,

  0,-2,-1,

  0,-2, 1,

  0,-1, 2 };

  main()

  { int a[9][9],object[9][9];

  int i,j,k,p,x,y,m,n,cont;

  int min,rm1,rm2,rm0=1;

  for(cont=1;cont>0;)

  { for(i=0;i<=8;i++) /* 保存个点度数的数组 清零 */

  for(j=0;j<=8;j++)

  a[i][j]=0;

  rm1=base[1][1]; /* 改变基础数组元素排列顺序 */

  rm2=base[1][2];

  base[1][1]=base[rm0][1];

  base[1][2]=base[rm0][2];

  base[rm0][1]= rm1;

  base[rm0][2]= rm2;

  for(i=1;i<=8;i++)

  { for(j=1;j<=8;j++) /* 计算各点度数存入数组a */

  { for(p=1;p<=8;p++)

  { x=i+base[p][1];

  y=j+base[p][2];

  if(x>=1&&x<=8&&y>=1&&y<=8)

  a[x][y]++;

  }

  printf(" %d",a[i][j]); /* 输出度数表 */

  }

  printf("\n");

  }

  printf("Please Input start position:line,colume=?\n");

  scanf("%d,%d",&i,&j); /* 输入起跳点坐标 */

  for(k=1;k<=63;k++) /* 求棋盘上63个落步点 */

  { object[i][j]=k; /* 跳步路径存入数组object */

  min=10;

  for(p=1;p<=8;p++) /* 求从当前起跳点出发的8个可能落点 */

  { x=i+base[p][1];

  y=j+base[p][2];

  if(x>=1&&x<=8&&y>=1&&y<=8) /* 求出的可能落点在棋盘内 */

  if(a[x][y]!=0) /* 此点没有落过棋子 */

  { a[x][y]--; /* 由于[i、j]点落过棋子,此点度数减1 */

  if(min>a[x][y]) /* 判断当前可能点度数是否最小 */

  { min=a[x][y]; /* 保存可能最小度数点的度数 */

  m=x; /* 保存可能最小度数点的坐标 */

  n=y;

  }

  }

  }

  a[i][j]=0; /* 落过棋子的[i、j]点度数为零 */

  i=m; /* 已求出的最小度数点为下次搜寻的起跳点 */

  j=n;

  }

  object[i][j] = 64 ;

  for(i=1;i<=8;++i) /* 输出跳步结果路径 */

  { for(j=1;j<=8;j++)

  if(j==8) printf("%2d",object[i][j]);

  else printf("%2d ",object[i][j]);

  printf("\n");

  if(i!=8) printf(" \n"); /* 每行输出8个数据 */

  }

  rm0%=8; /* 放在基础数组第一位的元素循环变化 */

  rm0++; /* 基础数组下一元素放在第一位 */

  printf("continue?(1 or 0)");

  scanf("%d",&cont);

  }

  }

  【4.79】分析:采用试探法求解。

  如图所示,用I、J表示行、列坐标。

  开始棋盘为空,对于第1个皇后先占用第一行即I=1,先试探它占用第一列J=1位置,则它所在的行、列和斜线方向都不可在放其它皇后了,用线将它们划掉。第2个皇后不能放在J=1、2的位置,试J=3。第2个皇后占用[2、3]后,它的行列和斜线方向也不可再放其它皇后。第3个皇后不能放在J=1、2、3、4的位置,试J=5。第4个皇后可以试位置[4、2],第5个皇后试位置[5、4]。第6个皇后已经没有可放的位置(棋盘上所有格子都已占满),说明前面所放位置不对。

  退回到前一个皇后5,释放它原来占用的位置[5、4],改试空位置[5、8]。然后再前进到第6个皇后,此时仍无位置可放,退回到第5个皇后,它已没有其它位置可选择。进一步退回到第4个皇后释放位置[4、2]改试位置[4、7],再前进到第5个皇后进行试探,如此继续,直到所有8个皇后都选择一个合适的位置,即可打印一个方案。

  然后从第8个皇后开始,改试其它空位置,若没有可改选的空位置,则退回到第7个皇后改试其它位置,若也没有空位置可改,继续退,直到有另外的空位置可选的皇后。将它原来占用的位置释放,改占其它新位置,然后前进到下一个皇后进行试探,直到所有8个皇后都找到合适位置,又求出一个解,打印输出新方案。按此方法可得到92个方案。

  参考答案:

  #define NUM 8

  int a[NUM+1];

  main()

  { int number,i,k,flag,nonfinish=1,count=0;

  i=1;

  a[1]=1;

  while(nonfinish)

  { while(nonfinish && i<=NUM)

  { for(flag=1,k=1;flag && k

  if(a[k]==a[i]) flag=0;

  for(k=1;flag && k

  if((a[i]==a[k]-(k-i)) || (a[i]==a[k]+(k-i))) flag=0;

  if(! flag)

  { if(a[i]==a[i-1])

  { i--;

  if(i>1 && a[i]==NUM) a[i]=1;

  else if(i==1 && a[i]==NUM) nonfinish=0;

  else a[i]++;

  }

  else if(a[i]==NUM) a[i]=1;

  else a[i]++;

  }

  else if( ++i<=NUM )

  if(a[i-1]==NUM) a[i]=1;

  else a[i]=a[i-1]+1;

  }

  if(nonfinish)

  { printf("\n%2d:",++count);

  for(k=1;k<=NUM;k++)

  printf(" %d",a[k]);

  if(a[NUM-1]

  else a[NUM-1]=1;

  i=NUM-1;

  }

  }

  }

  【4.80】参考答案:

  double findy(float x)

  { if(x>=0 && x<2)

  retuen(2.5-x);

  else if(x>=2 && x<4)

  return(2-1.5*(x-3)*(x-3)); else if(x>=4 && x<6)

  return(x/2.0-1.5);

  }

  main()

  { float x;

  printf("Please enter x:");

  scanf("%f",&x);

  if(x>=0 && x<6)

  printf("f(x)=%f\n",findy(x));

  else

  printf("x is out!\n");

  }

  【4.81】注释:此程序采用模拟手工方式,对分数进行通分后比较分子的大小。

  参考答案:

  main( )

  { int i, j, k, l, m, n;

  printf("Input two FENSHU :\n");

  scanf("%d/%d,%d/%d", &i, &j, &k, &l); /* 输入两个分数 */

  m = zxgb(j,l)/j * i; /* 求出第一个分数通分后的分子 */

  n = zxgb(j,l)/l * k; /* 求出第二个分数通分后的分子 */

  if(m>n )

  printf("%d/%d > %d/%d\n",i,j,k,l); /* 比较分子的大小 */

  else if(m==n)

  printf("%d/%d = %d/%d\n",i,j,k,l); /* 输出比较的结果 */

  else printf("%d/%d < %d/%d\n",i,j,k,l);

  }

  zxgb(a,b)

  int a,b;

  { long int c;

  int d;

  if(a

  for( c=a*b; b!=0; ) /* 用辗转相除法求a和b的最大公约数 */

  { d=b; b=a%b; a=d;

  }

  return((int) c/a); /* 返回最小公倍数 */

  }

  【4.82】参考答案:

  main()

  { int a[5],i,t,k;

  for (i=100;i<1000;i++)

  { for(t=0,k=1000;k>=10;t++)

  { a[t]=(i%k)/(k/10);

  k/=10;

  }

  if(f(a[0])+f(a[1])+f(a[2])==i)

  printf("%d ",i);

  }

  }

  f(m)

  int m;

  { int i=0,t=1;

  while(++i<=m) t*=i;

  return(t);

  }

  【4.83】分析:任取两个平方三位数n和n1,将n从高向低分解为a、b、c,将n1从高到低分解为x、y、z。判断ax、by、cz是否均为完全平方数。

  参考答案:

  main( )

  { void f( );

  int i,t,a[3],b[3];

  printf("The possible perfect squares combinations are:\n");

  for(i=11;i<=31;i++) /* 穷举平方三位数的取值范围 */

  for(t=11;t<=31;t++)

  { f(i*i,a); /* 分解平方三位数的各位,每位数字分别存入数组中 */

  f(t*t,b);

  if(sqrt(a[0]*10+b[0])==(int)sqrt(a[0]*10+b[0])

  && sqrt(a[1]*10+b[1])==(int)sqrt(a[1]*10+b[1])

  && sqrt(a[2]*10+b[2])==(int)sqrt(a[2]*10+b[2]))

  /* 若三个新的数均是完全平方数 */

  printf(" %d and %d\n",i*i,t*t); /* 则输出 */

  }

  }

  void f(n,s) /* 分解三位数n的各位数字,将各个数字 */

  int n, *s; /* 从高到低依次存入指针s所指向的数组中 */

  { int k;

  for(k=1000;k>=10;s++)

  { *s = (n%k)/(k/10);

  k /= 10;

  }

  }

  【4.84】参考答案:

  main()

  { int i,j,l,n,m,k,a[20][20];

  printf("Please enter n,m=");

  scanf("%d,%d",&n,&m);

  for(i=0;i

  for(j=0;j

  { printf("a[%d][%d]=",i,j);

  scanf("%d",&a[i][j]);

  }

  for(i=0;i

  { for(j=0;j

  printf("%6d",a[i][j]);

  printf("\n");

  }

  for(i=0;i

  { for(j=0,k=0;j

  if(a[i][j]>a[i][k]) k=j; /* 找出该行最大值 */

  for(l=0;l

  if(a[l][k]

  if(l>=n) /* 没有比a[i][k]小的数,循环变量l就超过最大值 */

  printf("Point:a[%d][%d]==%d",i,k,a[i][k]);

  }

  }

  【4.85】分析:按题目的要求进行分析,数字1一定是放在第一行第一列的格中,数字6一定是放在第二行第三列的格中。在实现时可用一个一维数组表示,前三个元素表示第一行,后三个元素表示第二行。先根据原题初始化数组,再根据题目中填写数字的要求进行试探。

  参考答案:

  #include

  int count; /* 计数器 */

  main( )

  { static int a[ ]={1,2,3,4,5,6}; /* 初始化数组 */

  printf("The possible table satisfied above conditions are:\n");

  for(a[1]=a[0]+1;a[1]<=5;++a[1]) /* a[1]必须大于a[0] */

  for(a[2]=a[1]+1;a[2]<=5;++a[2]) /* a[2]必须大于a[1] */

  for(a[3]=a[0]+1;a[3]<=5;++a[3]) /* 第二行的a[3]必须大于a[0] */

  for(a[4]=a[1]>a[3]?a[1]+1:a[3]+1;a[4]<=5;++a[4])

  /* 第二行的a[4]必须大于左侧a[3]和上边a[1] */

  if(jud1(a))

  print(a); /* 如果满足题意,打印结果 */

  }

  jud1(s) /* 判断数组中的数字是否有重复的 */

  int s[ ];

  { int i,l;

  for(l=1;l<4;l++)

  for(i=l+1;i<5;++i)

  if(s[l]==s[i])

  return(0); /* 若数组中的数字有重复的,返回0 */

  return(1);      /* 若数组中的数字没有重复的,返回1 */

  }

  print(u)

  int u[ ];

  { int k;

  printf("\nNo.:%d", ++count);

  for(k=0;k<6;k++)

  if(k%3==0) /* 输出数组的前三个元素作为第一行 */

  printf("\n %d ",u[k]);

  else /* 输出数组的后三个元素作为第二行 */

  printf("%d ",u[k]);

  }

  【4.86】参考答案:

  #include "string.h"

  strcmbn(a,b,c) /* 数组合并函数:将数组a、b合并到 */

  char a[],b[],c[];

  { char tmp;

  int i,j,k,m,n;

  m=strlen(a);

  n=strlen(b);

  for(i=0;i

  { for(j=i+1,k=i;j

  if(a[j]

  tmp=a[i]; a[i]=a[k]; a[k]=tmp;

  }

  for(i=0;i

  { for(j=i+1,k=i;j

  if(b[j]

  tmp=b[i]; b[i]=b[k]; b[k]=tmp;

  }

  i=0;j=0;k=0;

  while(i

  if(a[i]>b[j])

  c[k++]=b[j++]; /* 将a[i]、b[j]中的小者存入c[k] */

  else

  { c[k++]=a[i++];

  if(a[i-1]==b[j]) j++; /* 如果a、b当前元素相等,删掉一个 */

  }

  while(i

  while(j

  c[k]='\0';

  }

  【4.87】参考答案:

  pxn(x,n)

  float x;

  int n;

  { if(n==0) return(1);

  else if(n==1) return(x);

  else return(((2*n-1)*x*pxn(x,n-1)-(n-1)*pxn(x,n-2))/2);

  }

  【4.88】参考答案:

  #include "stdio.h"

  strout(s)

  char *s;

  { if(*s!='\0')

  { strout(s+1); /* 递归调用strout函数,字符串首地址前移一个字符 */

  putch(*s); /* 输出字符串首地址所指向的字符 */

  }

  else return; /* 遇到字符串结束标志结束递归调用 */

  }

  【4.89】参考答案:杨辉三角形中的数,正是(x+y)的N次方幂展开式中各项的系数。本题作为程序设计中具有代表性的题目,求解的方法很多(可以使用一维数组,也可以使用二维数组),前面我们给出用数组的答案,这里给出一种使用递归求解的方法。

  从杨辉三角形的特点出发,可以总结出:

  ⑴ 第N行有N+1个值(设起始行为第0行);

  ⑵ 对于第N行的第J个值: (N>=2)

  当J=1或J=N+1时: 其值为1

  当J!=1且J!=N+1时: 其值为第N-1行的第J-1个值与第N-1行第J个值之和。

  将这些特点提炼成数学公式可表示为:

  c(x,y) = 1 x=1 或 x=N+1

  c(x,y) = c(x-1,y-1) + c(x-1,y) 其它

  下面给出的程序就是根据以上递归的数学表达式编制的。

  参考答案:

  #include

  main( )

  { int i,j,n=13;

  printf("N=");

  while( n>12 )

  scanf("%d", &n); /* 最大输入值不能大于12 */

  for(i=0;i<=n;i++) /* 控制输出N行 */

  { for(j=0;j<12-i;j++)

  printf(" "); /* 控制输出第i行前面的空格 */

  for(j=1;j

  printf("%6d", c(i,j)); /* 输出第i行的第j个值 */

  printf("\n");

  }

  }

  int c(x,y) /* 求杨辉三角形中第x行第y列的值 */

  int x, y;

  { int z;

  if((y==1)||(y==x+1))

  return(1); /* 若为x行的第1或第x+1列,则输出1 */

  else /* 否则;其值为前一行中第y-1列与第y列值之和 */

  z = c(x-1,y-1) + c(x-1,y);

  return(z);

  }

  【4.90】分析:整型数在计算机中就是以二进制形式存储的,此题的目的仅是为了学习递归程序的编程。

  参考答案:

  turn(n,a,k)

  int n,a[ ],k;

  { if(n>0)

  { a[k]=n%2;

  turn(n/2,a,k-1);

  }

  else return;

  }

  main()

  { int i,n,a[16]={0};

  printf("\nPlease enter n:");

  scanf("%d",&n);

  turn(n,a,15);

  for(i=0;i<16;i++)

  printf("%d",a[i]);

首页 1 2 3 尾页
责编:zhangjing0102