算法课习题汇总(2)

整数划分问题

将正整数n表示成一系列正整数之和,n=n1+n2+...+nk(n1>=n2>=...>=nk,k>=1)。正整数n的这种表示称为正整数n的划分。

思路:

n表示待划分数,m表示最大减数。

cpp 复制代码
#include<iostream>
using namespace std;

int q(int n, int m)
{
	if (m == 1)
		return 1;
	if (m > n)
		return q(n, n);
	if (n == m)
		return q(n, n-1) + 1;
	return q(n - m, m) + q(n, m-1);
}

int main()
{
	int n = 0;
	cin >> n;
	cout << q(n, n) << endl;
	return 0;
}

Hanoi问题 T(n)=2^n-1

具体看:汉诺塔问题

cpp 复制代码
#include<iostream>
using namespace std;

void move(char A, char B)
{
	cout << A <<"->" << B << endl;
}

void hanoi(int n, char A, char B, char C)
{
	if (n == 0)
		return;
	hanoi(n - 1, A, C, B);
	move(A, B);
	hanoi(n - 1, C, B, A);
}

int main()
{
	int n = 0;
	cin >> n;
	hanoi(n,'A','B','C');
	return 0;
}

二分搜索 O(n)=nlogn

cpp 复制代码
int Search(int* arr, int x, int n)
{
	int left = 0;
	int right = n;
	while (left <= right)
	{
		int mid = left + (right - left) / 2;
		if (x == arr[mid])
			return mid;
		else if (x > arr[mid])
			left = mid + 1;
		else
			right = mid - 1;
	}
	return -1;
}

int main()
{
	int n = 0;
	cin >> n;
	int arr[1000];
	for (int i = 0; i < n; i++)
		cin >> arr[i];
	cout << Search(arr, 5, n - 1) << endl;
	return 0;
}

合并排序 O(n)=nlogn

cpp 复制代码
#include<iostream>
using namespace std;

void Merge(int* arr, int l, int r)
{
	if (l == r)
		return;
	int mid = l + (r - l) / 2;
	Merge(arr, l, mid);
	Merge(arr, mid + 1, r);
	int i = l, j = mid + 1, k = l;
	int arr2[10000] = {0};
	while (i <= mid && j <= r)
	{
		if (arr[i] >= arr[j])
		{
			arr2[k++] = arr[j++];
		}
		else
		{
			arr2[k++] = arr[i++];
		}
	}
	while (i <= mid)
	{
		arr2[k++] = arr[i++];
	}
	while (j <= r)
	{
		arr2[k++] = arr[j++];
	}
	for (i = l; i <= r; i++)
	{
		arr[i] = arr2[i];
	}
}

int main()
{
	int n;
	cin >> n;
	int arr[10000];
	for (int i = 0; i < n; i++)
		cin >> arr[i];
	Merge(arr, 0, n - 1);
	for (int i = 0; i < n; i++)
		cout << arr[i]<<" ";
	cout << endl;
	return 0;
}

快速排序 O(n)=nlogn

cpp 复制代码
#include<iostream>
using namespace std;

void q(int* arr, int l, int r)
{
	if (l >= r)
		return;
	int mid=l+(r-l)/2;
	swap(arr[1], arr[mid]);
	int tmp = arr[1];
	int i = l, j = r;
	while (1)
	{
		while (i < j && arr[j] >= tmp)
			j--;
		while (i < j && arr[i] <= tmp)
			i++;
		if (i >= j)
			break;
		swap(arr[i], arr[j]);
	}
	swap(arr[i],arr[1]);
	q(arr, l, i - 1);
	q(arr, i + 1, r);
}

int main()
{
	int n;
	cin >> n;
	int arr[100];
	for (int i = 0; i < n; i++)
		cin >> arr[i];
	q(arr, 0, n - 1);
	for (int i = 0; i < n; i++)
		cout << arr[i]<<" ";
	cout << endl;
	return 0;
}
相关推荐
太阳照常升起36614 分钟前
机试准备第一天
算法
Non importa16 分钟前
【初阶数据结构】线性表之单链表
数据结构·考研·算法·链表·github·学习方法
fanstuck30 分钟前
如何快速准备数学建模?
算法·数学建模·数据挖掘
Static_Xiao1 小时前
C语言导航 7.1函数的概念与定义
c语言·数据结构·算法
萌の鱼1 小时前
leetcode 53. 最大子数组和
数据结构·c++·算法·leetcode
水水阿水水1 小时前
第二章:面向对象之封装(一)
开发语言·c++·算法
圆圆滚滚小企鹅。1 小时前
刷题记录 回溯算法-5:17.电话号码的字母组合
数据结构·python·算法·leetcode
云川之下1 小时前
【k8s】scc权限 restricted、anyuid、privileged
算法
JLiuli1 小时前
排序算法——堆排序
数据结构·算法·排序算法
奔跑de自由1 小时前
C 语言内存秘籍:memcpy 等四函数的实用指南与底层解析
c语言·数据结构·算法