挑战程序设计竞赛 算法和数据结构 第6章 递归和分治法

挑战程序设计竞赛 算法和数据结构 第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该章节

深刻体会,递归需要时间的积累,需要多想多思。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值