算法复习(递归与分治)

半数集

描述

给定一个自然数n,由n 开始可以依次产生半数集set(n)中的数如下。
(1) n∈set(n);
(2) 在n 的左边加上一个自然数,但该自然数不能超过最近添加的数的一半;
(3) 按此规则进行处理,直到不能再添加自然数为止。
例如,set(6)={6,16,26,126,36,136}。半数集set(6)中有6 个元素。

输入

输入一个自然数n

输出

半数集中数的个数

#include<iostream>

using namespace std;

int halfset(int n) {
	int sum = 1;
	for (int i = 1; i <= n / 2; i++) {
		sum += halfset(i);//递归调用,计算不超过该数一半的所有情况
	}
	return sum;
}
int main() {
	int n;
	cin >> n;
	cout << halfset(n) << endl;
	return 0;
}

放苹果(盘子相同)

描述

把M个同样的苹果放在N个同样的盘子里,允许有的盘子空着不放,问共有多少种不同的分法?(用K表示)5,1,1和1,5,1 是同一种分法。

输入

苹果个数m 和盘子个数n(0<=M,1<=N<=10)

输出

不同的放法数目

#include<iostream>

using namespace std;

int apple(int m, int n) {
	if (m == 0 || n == 1)
		return 1;//没有苹果或盘子数为1的情况
	else if (n > m)
		return apple(m, m);//盘子多于苹果时,多余的盘子不会使用到
	else
		return apple(m, n - 1) + apple(m - n, n);//有空盘子的情况加上没有空盘子的情况
}
int main() {
	int m, n;
	cin >> m >> n;
	cout << apple(m, n);
	return 0;
}

判堆

描述

输入一个长度为N的序列A[1...N],请你判断其是否构成一个堆。

输入

第一行1个整数N
第二行N个int范围整数A[i],空格隔开

输出

输出1行
如果同时构成大根/小根堆,输出“Both”;
如果构成大根堆,输出“Max Heap”;
如果构成小根堆,输出“Min Heap”;
否则,输出“Not Heap”

#include<iostream>

using namespace std;

bool IsMinHeap(int a[], int len) {//判断小根堆
	if (len % 2 == 0) {//数组长度为偶数,最后一个分支只有左子树
		if (a[len] < a[len / 2])//判断单独的左子树
			return false;
		else {
			for (int i = len / 2 - 1; i > 0; i--) {
				if (a[i] > a[2 * i] || a[i] > a[2 * i + 1]) {
					return false;
				}
			}
		}//左右子树必须满足比根大
	}
	else {//最后一个分支有左右子树
		for (int i = len / 2; i > 0; i--) {
			if (a[i] > a[2 * i] || a[i] > a[2 * i + 1]) {
				return false;
			}
		}
	}
	return true;
}
bool IsMaxHeap(int a[], int len) {//大根堆
	if (len % 2 == 0) {
		if (a[len] > a[len / 2]) {
			return false;
		}
		else {
			for (int i = len / 2 - 1; i > 0; i--) {
				if (a[i] < a[2 * i] || a[i] < a[2 * i + 1]) {
					return false;
				}
			}
		}
	}
	else {
		for (int i = len / 2; i > 0; i--) {
			if (a[i] < a[2 * i] || a[i] < a[2 * i + 1]) {
				return false;
			}
		}
	}
	return true;
}
int main() {
	int n;
	cin >> n;
	int a[1000000] = { 0 };
	for (int i = 1; i <= n; i++) {
		cin >> a[i];
	}
	int(*p)[1000000];
	p = &a;
	if (IsMinHeap(*p, n) && IsMaxHeap(*p, n)){
		cout<<"Both";
	}
	if (IsMinHeap(*p, n) && !IsMaxHeap(*p, n)) {
		cout << "Min Heap";
	}
	if (!IsMinHeap(*p, n) && IsMaxHeap(*p, n)) {
		cout << "Max Heap";
	}
	if (!IsMinHeap(*p, n) && !IsMaxHeap(*p, n)) {
		cout << "Not Heap";
	}
	return 0;
}

全排列

描述

输入一个n,输出1~n之间数的全排列(n<=5)

输入

n

输出

全排列

#include<iostream>

using namespace std;

void quanpai(int *a, int index, int n) {
	if (index == n + 1) {//前n个全部处理完成,进行输出
		for (int i = 1; i <= n; i++) {
			cout << a[i] << " ";
		}
		cout << endl;
	}
	else {
		for (int i = index; i <= n; i++) {
			swap(a[i], a[index]);//交换两数,实现全排列
			quanpai(a, index + 1, n);//递归调用,逐步固定前n-1个数
			swap(a[i], a[index]);//恢复原来的序列
		}
	}
}
int main() {
	int n;
	cin >> n;
	int a[100] = { 0 };
	for (int i = 1; i <= n; i++) {
		a[i] = i;
	}
	int(*p)[100];
	p = &a;
	quanpai(*p, 1, n);
	return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值