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;
}