算法分析与设计考试算法

分治—快速排序

#include
#include
#include
using namespace std;
const int N=1e5+10;
int tmp[N];
int n;
void quick_sort(int l,int r)
{
     
	if(l>=r) return;
	int mod=tmp[l+r>>1],i=l-1,j=r+1;
	while(i<j)
	{
     
		do i++;while(tmp[i]<mod);
		do j--;while(tmp[j]>mod);
		if(i<j) swap(tmp[i],tmp[j]);
	}
	quick_sort(l,j);
	quick_sort(j+1,r);
}
int main()
{
     
	scanf("%d",&n);
	for(int i=0;i<n;i++) scanf("%d",&tmp[i]);
	quick_sort(0,n-1);
	for(int i=0;i<n;i++) printf("%d ",tmp[i]);
	
	return 0;
}
/*
5
1 3 2 5 4
*/

分治—归并排序

#include
#include
#include
using namespace std;
const int N=1e5+10;
int tmp[N];
int q[N];
void merge(int l,int r)
{
     
	if(l>=r) return;
	int mod=l+r>>1;
	merge(l,mod);
	merge(mod+1,r);
	int i=l,j=mod+1,k=0;
	while(i<=mod&&j<=r)
		if(tmp[i]<=tmp[j]) q[k++]=tmp[i++];
		else q[k++]=tmp[j++];
	while(i<=mod) q[k++]=tmp[i++];
	while(j<=r) q[k++]=tmp[j++];
	for(int i=0,j=l;i<k;i++,j++) tmp[j]=q[i];
}
int main()
{
     
	int n;
	scanf("%d",&n);
	for(int i=0;i<n;i++) scanf("%d",&tmp[i]);
	merge(0,n-1);
	for(int i=0;i<n;i++) printf("%d ",tmp[i]);
	return 0;
}

动态规划——数塔

#include
#include
#include
using namespace std;
const int N=1e3+10;
int q[N][N];
int n;
int main()
{
     
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
		for(int j=1;j<=i;j++)
			scanf("%d",&q[i][j]);
	for(int i=n-1;i>=1;i--)
		for(int j=1;j<=i;j++)
			q[i][j]=max(q[i+1][j],q[i+1][j+1])+q[i][j];
	printf("%d\n",q[1][1]);
	
	return 0;
}
/*
5
1 
2 3
3 4 5
4 5 6 7
4 6 8 2 10
*/

递归—汉诺塔

#include
#include
#include
using namespace std;
void move(int n,char A,char B,char C)
{
     
	if(n==1)
		printf("%c-->%c\n",A,C);
	else 
	{
     
		move(n-1,A,C,B);
		printf("%c-->%c\n",A,C);
		move(n-1,B,A,C);
		printf("%c-->%c\n",A,C);
	}
}
int main()
{
     
	int n;
	scanf("%d",&n);
	move(n,'A','B','C');
	
	return 0;
}

递归—最大公约数
最小公倍数可以由最大公约数来求得

#include
#include
#include
using namespace std;
//不用管a,b的大小关系,当ab
int gcd(int a,int b)
{
     
	return b?gcd(b,a%b):a;//这里三目运算符,判断b!=0
}
int main()
{
     
	int a,b;
	scanf("%d %d",&a,&b);
	printf("%d\n",gcd(a,b));
	return 0;
}
/*
2 4
3 5
2 8
8 10
*/

递归求斐波那契数

#include
#include
#include
using namespace std;
int f(int n)
{
     
	if(n==1||n==2)
		return 1;
	else return f(n-1)+f(n-2);
}
int main()
{
     
	int n;
	scanf("%d",&n);
	printf("%d\n",f(n));
	return 0;
}
//1 1 2 3 5 8 13 21

非递归求斐波那契
斐波那契数在第90多次的时候会超过 1 0 18 10^{18} 1018,因此用 l o n g   l o n g long\ long long long类型来存结果,求前90项。

#include
#include
#include
using namespace std;
typedef long long ll;
const int N=100;
ll f[N];
void init()
{
     
	f[1]=1;
	f[2]=1;
	for(int i=3;i<=90;i++) f[i]=f[i-1]+f[i-2];
}
int main()
{
     
	int n;
	init();
	scanf("%d",&n);
	printf("%lld\n",f[n]);
	return 0;
}

贪心-换钱币
换钱问题要求钱币面值要之前存在最小2倍关系,否则则转化为了完全背包问题
代码如下:

#include
#include
#include
using namespace std;
int q[10]={
     100,50,20,10,5,1};//可以自己改
int f[10];//用来存每张钱币的数量,定义为全局,初始为0 
int main()
{
     
	int n;
	int ant=0;
	scanf("%d",&n);//输入钱币数
	for(int i=0;i<6;i++)
		while(n>=q[i])
		{
     
			n-=q[i];
			f[i]++;
			ant++;
		 }
	printf("钱币张数%d\n",ant);
	for(int i=0;i<6;i++)
		for(int j=f[i];j>0;j--)
			printf("%d ",q[i]); 
	return 0;
 } 
/*
620
60
74
*/
#include
#include
#include
using namespace std;
int q[10]={
     100,50,20,10,5,2,1};
int f[10];//用来存每张钱币的数量,定义为全局,初始为0 
int main()
{
     
	int n;
	int ant=0;
	scanf("%d",&n);//输入钱币数
	for(int i=0;i<=6;i++)
	{
     
		f[i]=n/q[i];//改成除法,会快一些
		ant+=f[i];
		n=n-n/q[i]*q[i];
	}
	printf("钱币张数%d\n",ant);
	for(int i=0;i<=6;i++)
		for(int j=f[i];j>0;j--)
			printf("%d ",q[i]); 
	return 0;
 } 

你可能感兴趣的:(算法)