7.1 1 99个数分成三组,分别组成三个三位数,且使这三个三位数构成    1 : 2: 3
的比例,试求出所有满足条件的三个三位数。例如:三个三位数    192384576满足以上条
件。(1~9每个数字在3个三位数中都需要用一次且只能用一次   
分析:
1~99个数字组成3个三位数,假设每一个位上的数字表示一个    位置,用它代表数
a[i]的下标,即可以表示    a[1]~ a[9]的下标。
置数组a的每一个元素为 0,对于3个三位数中的每一个出现的数字    i,则赋值a[i]=1;
最后,如果a[1]+a[2]++a[9]==9,那么就表示 3个三位数中1~9分别出现一次且只出 现一次,即没有出现重复的数字!
【代码】
#include vstdio.h>
void main() {
int i, j, k, h, s;
int a[10];
for (i=123; i*3<=987 ; i++) {
for (h=1; h<10; h++) a[h]=0;
a[i/100]=1; a[i/10%10]=1;
a[i%10]=1;
j=i*2 ;
a[j/100]=1; a[j/10%10]=1;
a[j%10]=1;
k=i*3 ;
a[k/100]=1; a[k/10%10]=1;
a[k%10]=1;
for (s=0, h=1; h<10; h++) s=s+a[h];
if (s==9) printf("i=%d, j=%d, k=%d\n", i, j, k);
}
}
7.2 Armstrong数具有如下特征:一个    n位数等于其各位数的    n次方之和。如:
3    3    3
153=1    5 3
数据结构与算法分析答案4    4    4    4
1634=1 6    3 4
2345位的所有 Armstrong数。
枚举法:首先判断    num的位数n,然后判断它是否等于各位数的    n次方之和。
【代码】
#include vstdio.h>
int digitLen(long m);    // 求整数 m 的位数
int judgeEqual(long m);    // 判断整数 m 是否为 Armstrong
void main() {
long num; int n=0;
printf("All 2 digit to 5 digit Armstrong integers are following:");
for (num=10; numv=99999; num++) {
if (judgeEqual( num)) {
printf("%ld, ", num);
n++;
if (n%5==0) printf(    n
}
}
}
int digitLen(long m) {    //用于求给定参数 m的位数
int len=0;
do {
len++;
m=m/10;
} while ( m);
return len;
}
int judgeEqual(long m) {
//用于判断 m是否等于各位数的 n次方之和,即 m是否为Armstrong
int i, j, d;
long temp=m, p, sum=0;
n=digitLen(m) ;    // 计算 m 的长度
for (i=1; iv=n; i++) {
p=d=temp%10;
for (j=2; jv=n; j++)    // 计算 dn
p=p*d;
sum+=p;
temp=temp/10;
}
if (m==sum) return 1;
else return 0;
}
7.3 abc cba等于给定值 n的所有abc的组合。
//规定:一个整数的第一位(即最左一位)不能为    0,则ac不能为0
【代码】
#include vstdio.h>
void main() {
int n, a, b, c;
printf("please input a number to n:\n");
scanf("%d", &n);
for(a=1; a<=9; a++)
for (b=0; b<=9; b++)
for (c=1; c<=9; c++)
if (n==a*101+c*101+20*b)
printf(" %d = %d%d%d + %d%d%d \n", n, a, b, c, c, b, a);
}
7.7 搬砖问题:36块砖,36人搬,男搬4块,女搬3块,小孩两人抬一块,要求一次 搬完,问男、女、小孩各需多少人。
穷举法:
【代码】
#include<stdio.h>
void main() {
int child, girl;
for (child=0; child<=36; child=child+2 )    // child 表示小孩的数量
for (girl=0; girl<=12; girl++)    // girl 表示女人的数量
if (child/2 +3*girl +(36- child- girl)*4 == 36)    //    36 人共搬 36
printf("boy: %d, girl: %d, child: %d\n",    36 - child - girl, girl, child);
}
7.8 赛手:两个羽毛球队进行比赛,各出三人。甲队为    ABC三人,乙队为 X
YZ三人。已抽签决定比赛名单。有人向队员打听比赛名单。    A说他不和X比,C说他不
XZ比,请编写一个程序出三队赛手的名单。
【代码】
#include vstdio.h >
void main() {
char i, j, k; // iA的对手,jB的对手,kC的对手 for (i='X'; iv='Z'; i++) for (j=X; jv='Z'; j++) { if (i==j) continue;
for (k=X; kv='Z'; k++) {
if (i==k || j==k) continue;
if (i!='X' && k!='X' && k!='Z') printf( "order is A--%c,    B--%c,    C--%c\n ", i, j, k);
}
}
}
7.16 已知 Ackerman函数对于整数 m>0n> 0有如下定义:
ack(0, n) =n 1
ack(m, 0) =ack(m T, 1)
ack(m, n) =ack(m T, ack(m, n -1))
编写C程序,计算 ack(m, n)的值(mn的值由键盘输入)
//会出现递归的错误使用,层次太多,没有出口,发生堆栈溢出,请老师给出修改意见
【代码】
#include <stdio.h>
int ack(int m, int n) {
int s;
if (m==0) s=n+1;
else if (n==0) s=ack(m -1, 1);
else s=ack(m-1, ack(m, n -1)); return s;
}
void main() {
int s, m, n; printf("please input two positive numbers to m & n:\n"); scanf("%d%d", &m, & n);
s=ack(m, n); printf("%d\n", s);
7.17 用递归函数描述求两个正整数的最大公约数的过程。 代码】
#include <stdio.h>
int G_CD(int m, int n) {
if (m%n==0) return n;
else return G_CD( n, m%n );
}
void main() {
int a, b;
printf("please input two positive numbers to a and b:\n"); scanf("%d%d", &a, &b);
G_CD( a, b));
printf("The greatest common divisor of a and b is: %d\n", }
7.18 写出折半查的递归算法。
代码】 #include <stdio.h> int find(int a[], int x, int low, int high) { int mid; if (low>high) return - 1;
mid=(low+high)/2;
if (x>a[mid]) return find(a, x, mid+1 , high);
else if (x<a[mid]) return find(a, x, low, mid- 1);
else // x==a[mid] return mid;
}
void main() {
int a[10]={5, 7, 10, 15, 30, 45, 50, 66, 70, 88}; int x, loc;
printf("please input the numbers which we want to seek:\n"); scanf("%d", &x);
loc=find(a, x, 0, sizeof(a)/sizeof(a[0]) - 1);
if (loc== - 1) printf("No find!\n");
else printf("Find success, location is: %d\n", loc+1); }
7.4 梯有N阶,上楼可以一步上一阶,也可以一次上二阶。编一个程序,计算共有多
少种不同的走法。
count+=JieChen(i+j)/(JieChen(i)*JieChen(j));
//解法二
for (j=0; jv=N/2; j++) {    //对每一种组合再算组合
i=N - 2*j;
count+=JieChen(i+j)/(JieChen(i)*JieChen(j));
}
printf("%ld\n", count); }
// N=1 2    34567 89 10 级台阶
/
/ 1 2    3 5 8 13 21 34 55 89 种走法
7.10用穷举法生成    n阶魔方。所谓 n阶魔方,是指这样一种    nxn的方阵,如果将    n2
个自然数1 n2分别填在它的n2个不同的格子中,它的每行之和、每列之和、每主对角线    (