十分遗憾,1个月后我才再次在这里写东西.这其中经历了考试,世界杯,电脑修理,各种苦辣酸甜都在里面.幸好现在放假了,什么都不说了,开始吧.
这是第一集"SoftExam程序"的续集(一集也有续集?...)关于一些此类问题的两个程序,不是原创,是收集到的.
A非递归的程序:这是在看到问题的地方的答案,说起来还是非递归的程序更加有趣一点...
#define N 100
int a[N],r[N];
void nd(int n){
int i,k;
k=0;
r[0]=n;
do{
if(r[k]<=0){
printf("%d=%d",a[0],a[1]);
for(i=2;i<=k;i++)
printf("+%d",a[i]);
printf("/n");
while(k>0&&a[k]<=1) k--;
if(k>0) {a[k]--;r[k]++;}
}
else {
a[k+1]=a[k]<r[k]?a[k]:r[k];//give the smaller
r[k+1]=r[k]-a[k+1];
k++;
}
}while(k>0);
}
使用时候要先将要计算的数赋给a[0](好土气的方法),例如:
a[0]=4;
nd(a[0]);
其本质思想是:仍然将其计算的过程放到a中,把减剩下需要近一步减的放到r中(可以有0)
其过程似乎是一个回溯,一直减小,直到1再回溯将遇到的第一个不为1的数减1,再一步步的减小.
遗憾的是这程序不是我写的,看来解决一个算法问题还是要先多做几次人工的试验,充分了解了以后再开始写.
B计算有多少种分解方法的程序:这是我在王晓东的算法教材上看到的例子(这厮在N个不同的出版社出了N本完全相同算法教材,而且还没地方找答案去),非常典型的递归程序.
#include <stdio.h>
#include <stdlib.h>
int q(int n,int m){
if((n<1)||(m<1)) return 0;
if((n==1)||(m==1)) return 1;
if(n<m) return q(n,n);
if(n==m) return q(n,m-1)+1;
return q(n,m-1)+q(n-m,m);
}
int main(){
printf("%d/n",q(4,4));
}
道理很简单,把n分解成最大不大于m的和形式有多少种方法,最普遍的方法为分两个步骤:n分解为不大于m-1的种类数加上确定第一个为m的分解的种类数.当然还要包括一些特殊情况.
模拟卷子上还有递归程序的解法,但是错误的,我也懒得改了,至少还有我那个递归程序.