算法设计与分析基础 第三版 课后答案1.1

1.1.5

#include <iostream>
using namespace std;
int a[]={2,5,5,5};
int b[]={2,2,3,5,5,7};
int i,j;
int main(){
    while(i<4&&j<6){
    if(a[i]==b[j]){
        cout<<a[i]<<" ";
        i++;j++;
    }
    else if(a[i]>b[j]){
        j++;
    }
    else i++;
    }
    return 0;
}

1.1.6
a

#include <iostream>
using namespace std;
int gcd(int a,int b){
    if(b==0)return a;
    gcd(b,a%b);
}
int main(){
    cout<<gcd(31415,14142);
    return 0;
}
//输出结果:1

b
gcd算法:11次
min算法:14142-214142次
快14142/11-2
14142/11倍
约为1300-2600
1.1.7
设r=m mod n
则r=m-qn
d能整除m,n,就能整除m-qn
所以gcd(m,n)=gcd(n,m mod n)
1.1.8
会交换m和n
gcd(m,n)=gcd(n,m)
发生1次
1.1.9
a 1次
b 5次
1.1.10b 欧几里得游戏
相减最后得到最大公约数x,最初两数m=ix,n=jx,得到不同数字,需要写出所有倍数,写的次数为max(i,j)。若max(i,j)为奇数,先手赢;为偶数,后手赢。

#include <iostream>
#include <algorithm>
using namespace std;
int gcd(int a,int b){
    return a%b==0?a:gcd(b,a%b);
}
int main(){
    int m,n;cin>>m>>n;
    c=max(m,n);
    g=gcd(m,n);
    if((c/g)%2)cout<<"先手";
    else cout<<"后手";
    return 0;
}

1.1.11
a

int exgcd(int a,int b,int &x,int &y){
    if(b==0){x=1;y=0;return a;}
    int ans=exgcd(b,a%b,x,y);
    int temp=x;
    x=y;
    y=temp-a/b*y;
    return ans;
}

b
1.ax+by=gcd(a,b) 求得x,y,gcd(a,b)
2.if(!c%gcd(a,b))无整数解,退出
else 继续
3.已知x,y,c,gcd(a,b)求得x0=xc/gcd(a,b),y0=yc/gcd(a,b)
4.求得通解
x1=x0+kb/gcd(a,b)
y1=y0+k
a/gcd(a,b)
x1 = (x + k * ( b / gcd(a, b) )) (c / gcd(a, b) )
令 b1 = b / gcd(a, b)
x1 = (x1 % b1 + b1) % b1
y1 = (c - a
x1) / b

关于为何x1 = (x1 % b1 + b1) % b1:
x1=x0+k*b/gcd(a,b),则b/gcd(a,b)为x的解的周期,
设b1 = b/gcd,gcd不一定正,如果gcd为负将它取为正。对x,先x%b1得出最小的解,再将这个值加模取模,从而变为一个正数

例题洛谷P1516
1.1.12带锁的门
文字分析:https://blog.csdn.net/u012439764/article/details/81981748

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
int main(){
    int n;cin>>n;
    bool a[n+1]={0};
    for(int i=1;i<=n;i++){
        for(int j=i;j<=n;j++){
            if(!(j%i)){
                if(a[j])a[j]=0;
                else a[j]=1;
            }
        }
    }
    cout<<"open:";
    for(int i=1;i<=n;i++){
        if(a[i])cout<<i<<" ";
    }
    cout<<endl;
    cout<<"close:";
    for(int i=1;i<=n;i++){
        if(!a[i])cout<<i<<" ";
    }
    return 0;
}

答案为个人编写,全文手打,如有错误,还望指正

  • 5
    点赞
  • 46
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值