PTA数据结构134--137

7-134 正整数n不同分解式的个数

对于大于1的正整数n,可以分解为n=x1* x2 …… xm,其中xi>=2。例如n=12时有8种不同的分解,即12=12,12=6 * 2,12=4 * 3,12=3*4,12=3 * 2 * 2,12=2 * 6,12=2 * 3 * 2,12=2 * 2 * 3;设计一个算法求n的不同分解式的个数。(来源于《算法设计与分析(第2版)李春葆》)

答案:

#include<cmath>
#include<iostream>
#include<algorithm>
#include<cstdio>
 
using namespace std;
 
int a[10005], k;
int h[10005];
int n;
 
void divisor(int n){
    int i;
    for(i=1; i<sqrt(n); i++){
        if(n%i==0){
            a[k++] = i;
            a[k++] = n/i;
        }
    }
    
    if(i*i==n){
        a[k++] = i;
    }
    
}
int solve(){
    
    h[0]=1;
    for(int i=1; i<k; i++){
        for(int j=0; j<i; j++){
            if(a[i]%a[j]==0){
                h[i]+=h[j];
            }
        }
    }
    return h[k-1];
}
 
int main(){
    scanf("%d", &n);
    divisor(n);
    sort(a, a+k);
    cout<<solve()<<endl;
    return 0;
}

7-135 跳一跳

Drizzle 面前有一条由一堆非负整数组成的道路,从第一个数字起步,每次他都能跳出不大于当前数字的距离,每个数字之间的距离为1,那么他最少需要跳多少次才能到达终点?

答案:

#include<bits/stdc++.h>
using namespace std;
const int Max = 1e6+10;
int a[Max];
int find(int n, int m){
    int ans = n+1;
    for(int i = n; i <= m; i ++){
        if(a[n] < a[i]){
            a[n] = a[i];
            ans = i;
        }
    }
    return ans;
}
int link(int n, int m){
    int ans = n;
    for(int i = ans; i <= m; i ++){
        if(a[n] < a[i]+(i-n)){
            n = i;
        }
    }
    return n;
}
int main()
{
    int n;
    cin >> n;
    for(int i = 0; i < n; i ++){
        cin >> a[i];
    }
    int k = 0, tmp = 1; // 最少跳一次
    while(k+a[k] < n-1){
        int p = a[k]; // 防丢失
        int m = find(k,a[k]+k); // 寻找k到a[k]+k之内最大值所在的位置
        k = link(m,p+k); // 寻找要跳入的位置上
        tmp ++;
    }
    cout << tmp << endl;
}

7-136 后序和中序构造二叉树

本题目要求用后序序列和中序序列构造一棵二叉树(树中结点个数不超过10个),并输出其先序序列。

答案:

#include<bits/stdc++.h>
using namespace std;
typedef struct node{
    int val;
    struct node* left;
    struct node* right;
}*Bitree;
 
/*
如果数组p1=1 2 3 4 5
int* p2=p1+2;
p2为3 4 5
*/
Bitree createBitree(int* h,int* z,int size){
    //参数1:后续序列,参数2:中序序列,参数3:中序长度//
    if(size<1)return NULL;//如果中序长度小于1就表示该结点为空//
    Bitree p=(Bitree)malloc(sizeof(struct node));
    p->val=h[size-1];//当前后续序列的最后一位就是根结点//
    int f=0;//f用来计算当前结点的左子树结点数//
    while(z[f]!=h[size-1])f++;//中序序列中当前根结点的左边就是左子树序列//
    int r=size-f-1;//中序序列长度减去当前结点左子树长度再减去当前结点就是右子树长度//
    p->left=createBitree(h,z,f);//创建左子树//
    p->right=createBitree(h+f,z+f+1,r);//创建右子树//
    return p;
}
 
void qdisplay(Bitree t){
    if(t==NULL)return ;
    else{
        cout<<t->val<<' ';
        qdisplay(t->left);
        qdisplay(t->right);
    }
}
int main()
{
    ios::sync_with_stdio(false);
    int n;
    cin>>n;
    int h[100];
    int z[100];
    for(int i=0;i<n;i++){
        cin>>h[i];
    }
    for(int i=0;i<n;i++){
        cin>>z[i];
    }
    int size=n;//size记录当前中序长度//
    Bitree t=createBitree(h,z,size);//创建//
    qdisplay(t);//前序遍历验证//
    return 0;
}

7-137 先序和后序构造正则二叉树

本题目要求用先序序列和后序序列构造一棵正则二叉树(树中结点个数不超过10个),并输出其中序序列。

答案:

#include<bits/stdc++.h>
 
using namespace std;
 
const int N = 20;
 
int a[N],b[N];
vector<int>ans;
 
void get_zhong(int l1,int r1,int l2,int r2)
{
    if(l1 == r1)
    {
        ans.push_back(a[l1]);
        return ;
    }
    if(a[l1] == b[r2])
    {
        int i = l1 + 1;
        while(i <= r1 && a[i] != b[r2 - 1]) i++;
        if(i - l1 > 1)
            get_zhong(l1+1,i-1,l2,l2 + (i - l1 - 1) - 1);
        ans.push_back(b[r2]);
        get_zhong(i,r1,l2 + (i - l1 - 1),r2-1);
    }
}
 
int main()
{
    int n;
    cin>>n;
    for(int i=0;i<n;i++) cin>>a[i];
    for(int i=0;i<n;i++) cin>>b[i];
    get_zhong(0,n-1,0,n-1);
    for(int i=0;i<ans.size();i++)
        cout<<ans[i]<<' ';
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值