挑战程序设计竞赛 算法和数据结构 第6章 递归和分治法
6.2穷举搜索 ALDS1_5_A:Exhaustive Search
原书AC代码:
//ALDS1_5_A:Exhaustive Search
#include <stdio.h>
int n,A[50];
//从输入值M中减去所选元素的递归函数
int solve(int i,int m){
if(m==0)return 1;
if(i>=n)return 0;
int res = solve(i+1,m)||solve(i+1,m-A[i]);
return res;
}
int main(){
int q,M,i;
scanf("%d",&n);
for(i=0;i<n;i++)scanf("%d",&A[i]);
scanf("%d",&q);
for(i=0;i<q;i++){
scanf("%d",&M);
if(solve(0,M))printf("yes\n");
else printf("no\n");
}
return 0;
}
仿照上述代码,本人编写的C语言AC代码如下:
//ALDS1_5_A:Exhaustive Search
#include <stdio.h>
int A[30],n;
int search(int i,int m){
int res;
if(m==0)return 1;
if(i==n+1)return 0;
res=(search(i+1,m)||search(i+1,m-A[i]));
return res;
}
int main(){
int i,q,m;
scanf("%d",&n);
for(i=1;i<=n;i++)
scanf("%d",&A[i]);
scanf("%d",&q);
for(i=1;i<=q;i++){
scanf("%d",&m);
if(search(1,m))printf("yes\n");
else printf("no\n");
}
return 0;
}
2017-9-28 AC
6.3 科赫曲线 ALDS1_5_C:Koch Curve
原书AC代码:
//ALDS1_5_C:Koch Curve
#include <stdio.h>
#include <math.h>
struct Point{double x,y;};
void koch(int n,Point a,Point b){
if(n==0)return;
Point s,t,u;
double th = M_PI*60.0/180.0;//将单位从度变为弧度
s.x=(2.0*a.x+1.0*b.x)/3.0;
s.y=(2.0*a.y+1.0*b.y)/3.0;
t.x=(1.0*a.x+2.0*b.x)/3.0;
t.y=(1.0*a.y+2.0*b.y)/3.0;
u.x=(t.x-s.x)*cos(th)-(t.y-s.y)*sin(th)+s.x;
u.y=(t.x-s.x)*sin(th)+(t.y-s.y)*cos(th)+s.y;
koch(n-1,a,s);
printf("%.8f %.8f\n",s.x,s.y);
koch(n-1,s,u);
printf("%.8f %.8f\n",u.x,u.y);
koch(n-1,u,t);
printf("%.8f %.8f\n",t.x,t.y);
koch(n-1,t,b);
}
int main(){
Point a,b;
int n;
scanf("%d",&n);
a.x=0;
a.y=0;
b.x=100;
b.y=0;
printf("%.8f %.8f\n",a.x,a.y);
koch(n,a,b);
printf("%.8f %.8f\n",b.x,b.y);
return 0;
}
以下公式的理解,花了很长时间
u.x=(t.x-s.x)*cos(th)-(t.y-s.y)*sin(th)+s.x;
u.y=(t.x-s.x)*sin(th)+(t.y-s.y)*cos(th)+s.y;
现解释如下,个人认为上述公式的得出,不是靠画图推导得出,而是靠推理归纳得出的。
u点的位置只有两处,一处是水平线上的凸起,一处是斜线上的凸起。注意,该题中th等于60度
水平线上的凸起:等边三角形边长L=t.x-s.x
u.x=(t.x-s.x)/2+s.x 等价于 u.x=(t.x-s.x)/2-0+s.y
即 u.x=(t.x-s.x)*cos(th)-(t.y-s.y)*sin(th)+s.x
u.y=L*sin(th)+s.y 等价于 u.y=(t.x-s.x)*sin(th)+0+s.y
即 u.y=(t.x-s.x)*sin(th)+(t.y-s.y)*cos(th)+s.y
斜线上的凸起:等边三角形边长L t.x-s.x=L/2=L*cos(th) t.y-s.y=L*sin(th)
u.x=s.x-L/2 等价于 u.x=s.x+L/4-3L/4 等价于 u.x=s.x+L*cos(th)*cos(th)-L*sin(th)*sin(th)
即u.x=(t.x-s.x)*cos(th)-(t.y-s.y)*sin(th)+s.x
u.y=s.y+Lsin(th) 等价于 u.y=s.y+L*cos(th)*sin(th)+L*sin(th)*cos(th)
即u.y=(t.x-s.x)*sin(th)+(t.y-s.y)*cos(th)
综合上述两种情况,可得通式:
u.x=(t.x-s.x)*cos(th)-(t.y-s.y)*sin(th)+s.x;
u.y=(t.x-s.x)*sin(th)+(t.y-s.y)*cos(th)+s.y;(2010-9-28 22:36)
仿照上述代码,本人编写的C语言AC代码如下:
//ALDS1_5_C:Koch Curve
//2一个很致命的问题,将递归中的 s,t;局部变量写成全局变量
//深刻感觉递归,还需要时间的积累。2017-9-29 AC
#include <stdio.h>
#include <math.h>
struct Point{
double x,y;
}p1,p2;//2写成 p1,p2,s,t;
int n;
void koch(int step,struct Point a,struct Point b){
double th=M_PI*60/180;//弧度形式的60度
struct Point s,u,t;//2一个很致命的问题,将递归中的 s,t;局部变量写成全局变量
if(step==0)return;
s.x=(2*a.x+b.x)/3;
s.y=(2*a.y+b.y)/3;
t.x=(a.x+2*b.x)/3;
t.y=(a.y+2*b.y)/3;
u.x=(t.x-s.x)*cos(th)-(t.y-s.y)*sin(th)+s.x;
u.y=(t.x-s.x)*sin(th)+(t.y-s.y)*cos(th)+s.y;
koch(step-1,a,s);//1 此处写成 koch(n-1,a,s);
printf("%.8f %.8f\n",s.x,s.y);
koch(step-1,s,u);//1 此处写成 koch(n-1,s,u);
printf("%.8f %.8f\n",u.x,u.y);
koch(step-1,u,t);//1 此处写成 koch(n-1,u,t);
printf("%.8f %.8f\n",t.x,t.y);
koch(step-1,t,b);//1 此处写成 koch(n-1,t,b);
}
int main(){
p1.x=0,p1.y=0;
p2.x=100,p2.y=0;
scanf("%d",&n);
printf("%.8f %.8f\n",p1.x,p1.y);
koch(n,p1,p2);
printf("%.8f %.8f\n",p2.x,p2.y);
return 0;
}
2017-9-29 AC该章节
深刻体会,递归需要时间的积累,需要多想多思。