-
斐波那契数列
#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; }
-
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; }
-
最大公约数
#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; }
-
二分搜索技术
#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; }
- 合并排序
#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; }
- 快速排序
#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; }
- 线性时间选择
#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; }
- 活动安排问题
#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; }
- 背包问题
#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; }
- 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; }
- 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; }
- 着色问题
#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; }