算法设计代码

  1. 斐波那契数列

    #include <stdio.h>
    
    double f(int n) {
    	if(n==1||n==2) {
    		return 1;
    	} else {
    		return f(n-1) + f(n-2);
    	}
    }
    
    int main() {
    	int n;
    	double result;
    	scanf("%d",&n);
    	result=f(n);
    	printf("%.0f\n",result);
    	return 0;
    }
  2. N的阶乘

    #include <stdio.h>
    
    int f(int n) {
    	if(n==0||n==1) {
    		return 1;
    	} else {
    		return f(n-1) * n;
    	}
    }
    
    int main() {
    	int n,result;
    	scanf("%d", &n);
    	result=f(n);
    	printf( "%d\n",result);
    	return 0;
    }
  3. 最大公约数

    #include <stdio.h>
    
    int f(int m,int n) {
    	if(m%n==0) {
    		return n;
    	} else {
    		return f(n,m%n);
    	}
    }
    
    int main() {
    	int a,b,result;
    	scanf("%d %d", &a,&b);
    	result=f(a,b);
    	printf("%d\n",result);
    	return 0;
    }
  4. 二分搜索技术

    #include <stdio.h>
    
    int binarySearch(int a[], int x, int left, int right) {
    	int mid;
    	if(left > right) {
    		return -1;
    	} else {
    		mid = (left+right)/2;
    		if(a[mid]==x)return mid;
    		if(x<a[mid])return binarySearch(a,x,left,mid-1);
    		else return binarySearch(a,x,mid+1,right);
    	}
    }
    
    int main() {
    	int a[20],n,x,i,index;
    	scanf("%d", &n);
    	for(i = 0; i < n; i++ ) {
    		scanf("%d", &a[i]);
    	}
    	scanf("%d", &x);
    	index = binarySearch(a, x, 0, n-1);
    	printf("%d\n", index);
    	return 0;
    }
  5.  合并排序
    #include<stdio.h>
    
    void copy(int a[],int b[],int left,int right) {
    	while(left<=right) {
    		a[left]=b[left];
    		left++;
    	}
    }
    
    void merge(int a[],int left,int mid,int right) {
    	int b[10];// 假设最大数组大小为10
    	int i=left;
    	int j=mid+1;
    	int k=left;
    	while(i<=mid && j<=right) {
    		if(a[i]<=a[j]) {
    			b[k] = a[i];
    			i++;
    		} else {
    			b[k] = a[j];
    			j++;
    		}
    		k++;
    	}
    	if(i<=mid)
    		while(i<=mid) {
    			b[k] = a[i];
    			i++;
    			k++;
    		}
    	else if(j<=right)
    		while(j<=right) {
    			b[k] = a[j];
    			j++;
    			k++;
    		}
    	copy(a,b,left,right);
    }
    
    void mergeSort(int a[],int left,int right) {
    	if(left<right) {
    		int mid=(left+right)/2;
    		mergeSort(a,left,mid);
    		mergeSort(a,mid+1,right);
    		merge(a,left,mid,right);
    	}
    }
    
    int main() {
    	int a[10],i,n;
    	scanf("%d",&n);// 输入一个正整数n,表示无序序列中的元素个数
    	for(i=0; i<=n-1; i++)scanf("%d",&a[i]);// 输入n个整数,每两个整数之间用空格隔开
    	mergeSort(a,0,n-1);
    	for(i=0; i<=n-1; i++)
    		if(i<n-1)printf("%d ",a[i]);
    		else printf("%d\n",a[i]);
    	return 0;
    }
  6.  快速排序
    #include <stdio.h>
    
    int partition(int a[], int low, int high) {
    	int i = low;
    	int j = high;
    	int c = a[low]; 
    	while (i<=j) {
    		// 从左到右找到第一个大于基准的元素
    		while(i<=high && a[i]<=c){
    		 	i++;
    		 }
    		// 从右到左找到第一个小于等于基准的元素
    		while(j>=low && a[j]>c){
    			j--;
    		}
    		// 交换 
    		if(i<j){
    			int temp = a[i];
    			a[i] = a[j];
    			a[j] = temp;
    		}
    	}
    	// 交换 
    	a[low] = a[j];
    	a[j] = c;
    	return j; // 注意返回的是j而不是i
    }
    
    void quickSort(int a[], int left, int right) {
    	if(left<right) {
    		int index = partition(a, left, right);
    		quickSort(a, left, index-1);
    		quickSort(a, index+1, right);
    	}
    }
    
    int main() {
    	int a[10],i,n;
    	scanf("%d",&n);// 输入一个整数n,表示无序序列中的元素个数
    	for(i = 0; i < n; i++ ) {
    		scanf("%d",&a[i]);// 输入n个整数,每两个整数之间用空格隔开
    	}
    	quickSort(a, 0, n-1);
    	for (i = 0; i < n; i++) {
    		if(i<n-1) printf("%d ",a[i]);
    		else printf("%d\n",a[i]);
    	}
    	return 0;
    }
  7.  线性时间选择
    #include"stdio.h"
    
    int partition(int a[], int left, int right) {
    	int i=left, j=right;
    	int x=a[left];
    	while(i<=j) {
    		while(a[i]<=x && i<=j) i++;
    		while(a[j]>x && i<=j) j--;
    		if(i<=j) {
    			int t=a[i];
    			a[i]=a[j];
    			a[j]=t;
    			i++;
    			j--;
    		}
    	}
    	a[left]=a[j];
    	a[j]=x;
    	return j;
    }
    
    int select(int a[], int left, int right, int k) {
    	if(left==right) return a[left];
    	else {
    		int j = partition(a,left,right);
    		int length = j-left+1;
    		if(length==k){
    			return a[j];
    		} else if(k<length) {
    			return select(a,left,j-1,k);
    		} else {
    			return select(a,j+1,right,k-length);
    		}
    	}
    }
    
    int main() {
    	int a[100],i,n,k;
    	scanf("%d",&n);// 输入一个整数n,表示线性表的长度
    	for(i=0; i<n; i++) scanf("%d",&a[i]);// 输入n个整数,表示线性表中存储的具体数据
    	scanf("%d",&k);// 输入一个整数k,表示需要查找的第k个小元素
    	int result=select(a,0,n-1,k);
    	printf("%d\n",result);// 输出一个整数,表示第k个小元素的值
    	return 0;
    }
  8.  活动安排问题
    #include <stdio.h>
    
    struct action {
    	int s;// 存储活动开始时间
    	int f;// 存储活动结束时间
    	int id;// 存储活动的编号 
    	int x;// x=1表示选择了该活动,否则表示没有选择该活动 
    };
    
    int fun(struct action a[],int n) {
    	int i,j,sum;
    	j = 1;// j用于跟踪上一个选择的活动
    	a[j].x = 1;// 选择第一个活动
    	sum = 1;// 选择的活动数量
    	for(i=2;i<=n;i++) {
    		// 如果当前活动的开始时间大于等于上一个选择活动的结束时间,则选择该活动
    		if(a[i].s>=a[j].f) {
    			a[i].x = 1;// 选择当前活动
    			j = i;// 更新上一个选择的活动
    			sum++;// 增加选择的活动数量
    		} else {
    			a[i].x = 0;
    		}
    	}
    	return sum;
    }
    
    void sort(struct action a[],int n) {
    	int i,j;
    	for(i=1; i<=n-1; i++) { // 按照活动的结束时间进行升序排序 
    		for(j=1; j<=n-i; j++) {
    			if(a[j].f>a[j+1].f) {
    				struct action t=a[j];
    				a[j]=a[j+1];
    				a[j+1]=t;
    			}
    		}
    	}
    }
    
    int main() {
    	int i,n;
            struct action a[21]; // 0号单元不存储有效数据
    	scanf("%d", &n);// 输入一个整数,表示有n个活动
    	for(i=1; i<=n; i++) {
    		scanf("%d", &a[i].s);// 输入n个整数,分别表示每个活动的开始时间
    	}
    	for(i=1; i<=n; i++) {
    		scanf("%d", &a[i].f);// 输入n个整数,分别表示每个活动的结束时间
    	}
    	for(i=1; i<=n; i++) {
    		a[i].id=i;
    	}
    	sort(a,n);
    	int sum=fun(a,n);
    	printf("%d\n",sum);
    	for(i=1; i<=n; i++) {
    		printf("%d %d\n",a[i].id,a[i].x);
    	}
    	return 0;
    }
  9.  背包问题
    #include <stdio.h>
    
    struct good {
    	int w,v,id;// w,v,id分别表示物品的重量,价值和编号
    	double x;// x在0-1之间取值,表示该物品需要放多少到背包中
    	double ratio;// 单位重量的价值
    };
    
    void f(struct good goods[],int n,int c) {
    	for(int i=1; i<=n; i++) {
    		if(c==0) break;// 如果背包已满,结束循环
    		if(goods[i].w<=c) { // 如果物品可以完全放入背包
    			goods[i].x = 1;
    			c -= goods[i].w;
    		} else {
    			goods[i].x = (double)c / goods[i].w;
    			c = 0;
    		}
    	}
    }
    
    void sort(struct good goods[],int n) {
    	for(int i=1; i<=n-1; i++) { // 冒泡排序(降序)
    		for(int j=1; j<=n-i; j++) {
    			if(goods[j].ratio<goods[j+1].ratio) {
    				struct good temp;
    				temp=goods[j];
    				goods[j]=goods[j+1];
    				goods[j+1]=temp;
    			}
    		}
    	}
    }
    
    int main(void) {
    	int i,n,c;
    	struct good goods[21]; // 0号单元不存储有效数据
    	scanf("%d %d", &n,&c);// 输入物品的个数以及背包的容量n和c
    	for(i=1; i<=n; i++) {
    		scanf("%d", &goods[i].w);
    	}
    	for(i=1; i<=n; i++) {
    		scanf("%d", &goods[i].v);
    	}
    	for(i=1; i<=n; i++) {
    		goods[i].id=i;
    		goods[i].x=0;
    		goods[i].ratio=1.0*goods[i].v/goods[i].w;
    	}
    	sort(goods,n);// 按照单位价值排序
    	f(goods,n,c);
    	for(i=1; i<=n; i++) {
    		printf("%d %.2f\n",goods[i].id,goods[i].x);
    	}
    	return 0;
    }
  10.  0-1背包问题
    #include <stdio.h>
    // 为了方便编写限界函数,假设按照单位重量获利递减输入每个物品的重量和获利。
    
    int w[21]; // 存储物品重量,0号单元不存储有效数据
    int v[21]; // 存储物品价值,0号单元不存储有效数据
    int n;// 存储物品个数
    int c;// 存储背包容量
    int bestx[21]; // 最优解,0号单元不存储有效数据
    int x[21]; // 当前解,0号单元不存储有效数据
    int bestv;// 最优值
    int cv;// 当前已经放到背包中的物品价值
    int cw;// 当前已经放到背包中的物品重量
    
    double bound(int i) { // 计算剩余物品(i:n)的上界
    	int cleft=c-cw;  // 剩余容量
    	int b=0;   // b是一个临时变量
    	while(i<=n && w[i]<=cleft) {
    		cleft-=w[i];
    		b+=v[i];
    		i++;
    	}
    	if (i<=n) {
    		b+=1.0*v[i]/w[i]*cleft;  // 装满背包
    	}
    	return b;
    }
    
    void backtrack(int i) { // 搜索第i层结点
    	if(i>n) { // 到达叶结点考虑结束本次递归
    		if(cv>bestv) {
    			bestv = cv;// 更新最优值
    			for(int j=1;j<=n;j++) {
    				bestx[j] = x[j];
    			}
    		} 
    	} else {
    		if(cw+w[i]<=c) { // 搜索左子树:选择放入背包
    			x[i] = 1;// 选择第i个物品
    			cw += w[i];// 更新当前重量
    			cv += v[i];// 更新当前价值
    			backtrack(i+1);// 递归到下一个物品
    			cw -= w[i];// 撤销当前选择
    			cv -= v[i];// 撤销当前选择
    		}
    		x[i] = 0;
    		if(cv+bound(i+1)>bestv) { // 搜索右子树:不选择放入背包
    			backtrack(i+1); 
    		}
    	}
    }
    
    int main() {
    	scanf("%d %d",&n,&c);// 输入两个整数,分别表示n个物品和背包容量c 
    	for(int i=1; i<=n; i++) {
    		scanf("%d",&w[i]);// 输入n个整数,分别表示每个物品的重量
    	}
    	for(int i=1; i<=n; i++) {
    		scanf("%d",&v[i]);// 输入n个整数,分别表示每个物品的价值
    	}
    	cw=0;
    	cv=0;
    	backtrack(1);
    	printf("%d\n",bestv);// 输出最大价值
    	for(int i=1; i<=n; i++) {
    		printf("%d ",bestx[i]);// 输出最优解 
    	}
    	return 0;
    }
  11.  N皇后问题
    #include <stdio.h>
    #include <math.h>
    
    int x[11];// xi表示第i个皇后存放的列位置(假设第i个皇后放在棋盘中的第i行),0号不存储有效数据
    int sum=0;// 记录当前已找到的可行方案数量,初始化为0
    int n;// 存储皇后的个数
    
    int place(int i) { // 检查第i个皇后的列位置与前i-1个皇后的位列位置是否冲突
    	for(int j=1;j<i;j++) {
    		if(x[j]==x[i]||abs(x[j]-x[i])==abs(j-i)) {
    			return 0;
    		}
    	}
    	return 1;
    }
    
    void backtrack(int i) {
    	if(i>n) {
    		sum++;// 找到一个可行方案
    	} else {
    		for(int j=1;j<=n;j++) { // 尝试将第i个皇后放在第j列
    			x[i] = j;// 放置皇后
    			if(place(i)) {
    				backtrack(i+1);
    			}
    		}
    	}
    }
    
    int main() {
    	scanf("%d",&n);// 输入一个整数表示皇后的个数
    	backtrack(1);// 从第1个皇后开始放置
    	printf("%d\n",sum);// 输出满足条件的不同放法数量
    	return 0;
    }
  12.  着色问题
    #include<stdio.h>
    #include<string.h>
    
    int n;// 图中节点的个数
    int m;// 给定的颜色种类,编号从1到m
    int sum=0;// 保存可以着色的方案数
    int x[11];// xi记录第i个顶点着的颜色编号
    int a[11][11];// 表示图的邻接矩阵
    
    int OK(int i) { // 检验第i个顶点着的颜色是否与前i-1个顶点的着色有冲突
    	for(int j=1;j<i;j++) {
    		if(a[i][j]==1&&x[i]==x[j]) {
    			return 0;
    		}
    	}
    	return 1;
    }
    
    void backtrack(int i) {
    	if(i>n) {
    		sum++;// 找到一种可行的着色方案
    	} else {
    		for(int color=1;color<=m;color++) { // 尝试每种颜色
    			x[i] = color;// 给第i个顶点上色
    			if(OK(i)) {
    				backtrack(i+1);
    			}
    		}
    	}
    }
    
    int main() {
    	int i,j;
    	scanf("%d %d",&n,&m);// 输入两个整数,分别表示图中的顶点数n和给定的颜色数m
    	for(i=1;i<=n;i++){ // 每行输入n个0或1的整数序列(每两个整数之间用一个空格隔开),表示该图对应的邻接矩阵
    		for(j=1;j<=n;j++){
    			scanf("%d",&a[i][j]);
    		}
    	}
    	backtrack(1);
    	printf("%d\n",sum);
    	return 0;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值