【算法设计与分析】第一至六讲实验

1:

求最大公约数

【问题描述】求两个自然数m和n的最大公约数。

【评分标准】答案正确性及计算时间

#include<iostream>
using namespace std;
int CommFactor(int m, int n);

int main()
{
    int a, b, r;
    cin>>a>>b;
    r = CommFactor(a, b);
    cout<<r<<endl;
    return 0;
}
int CommFactor(int m, int n)
{
int r; 
	r = m % n;
	while(r!=0) 
	{
		m = n;
		n = r;
		r = m % n;
	}
    return n;
}

2:

n个重复数字求和问题

【问题描述】设计程序,该程序通过键盘输入获得整型数据a和n,计算sum=a+aa+aaa+...(共计n项),输出计算结果。

【输入形式】整形数据a和n,用空格隔开

【输出形式】求和结果

【样例输入】5 4

【样例输出】6170

【样例说明】如a=5,n=4,sum=5+55+555+5555

#include <cstdio>
 
//求和函数 
int getSum(int a,int n){
    int sum=0,last=a;
    for(int i=0;i<n;i++){
        sum+=a;
        //a+=a*10;
        a=a*10+last;//每次乘以10 加上末尾的数 
    }
    return sum;
}
 
int main(){
    int a,n;
    scanf("%d %d",&a,&n);
    int result=getSum(a,n);//调用求和函数 
    printf("%d",result);
    return 0;
}

求第k大的数

【问题描述】

求n个整数中第k大的数

【输入形式】

第一行输入n和k,第二行为n个整型数,都以空格分开

【输出形式】

第k大的数

【样例输入】

10 3

18 21 11 26 12 2 9 33 43 28

【样例输出】

28

【评分标准】

正确性与计算性能

#include <cstdio>
#include <malloc.h>
#include <search.h>
 
//快排cmp 
//int cmp(const void *a,const void *b){
//    return *(int*)a - *(int*)b;
//}
void QuickSort(int a[],int l,int r)
{
    int i,j,key;
    i=l;
    j=r;
    key=a[l];  //将第一个数作为基准数
    while(i<j)
    {
        while(i<j && key<=a[j])  //从数组后面开始,如果大于基准数,则跳过
        {
            j--;
        }
        if(i<j)     //找到第一个小于基准数的数,覆盖基准数的位置
        {
            a[i++]=a[j];
        }
        while(i<j && key>a[i])  //从数组前面开始,如果小于基准数,则跳过
        {
            i++;
        }
        if(i<j)     //找到第一个大于等于基准数的数,覆盖基准数的位置
        {
            a[j--]=a[i];
        }
    }
    a[i]=key;
    if(l<i-1)
    {
        QuickSort(a,l,i-1);
    }
    if(r>i+1)
    {
        QuickSort(a,i+1,r);
    }
}
 
int main(){
    int n,k;
    scanf("%d %d",&n,&k);
    int *ans=(int*)malloc(sizeof(int)*n);//定义一个数组空间ans 
    for(int i=0;i<n;i++){
        scanf("%d",&ans[i]);//依次存入数组 
    }
    
//    选择排序法 
//    for(int i=0;i<n;i++){
//        int minno=i;
//        for(int j=i+1;j<n;j++){
//            if(ans[j]<ans[minno]){
//                minno=j;
//            }
//        }
//        int temp=ans[minno];
//        ans[minno]=ans[i];
//        ans[i]=temp;
//    }
    
//    for(int i=0;i<n;i++){
//        printf("%d ",ans[i]);
//    }
//    printf("\n");
 
    QuickSort(ans,0,n-1);
    
    printf("%d",ans[n-k]);//打印结果 
    return 0;
}

 3:

整数排序

【问题描述】

从标准输入中输入一组互不相同的整数(个数不超过100)及排序方式,按照从小到大排序,输出按某种算法排序的结果及元素的比较次数。

【输入形式】

首先在屏幕上输入1个整数,表示待排序的整数个数,然后在下一行依次输入待排序的整数。各整数之间都以一个空格分隔。

【输出形式】

在一行上输出排序结果,各整数间以一个空格分隔。

【样例1输入】

10

46 65 -9 100 0 21 2 90 8 18

【样例1输出】

-9 0 2 8 18 21 46 65 90 100

【评分标准】

该题要求按照指定算法对输入的数据进行排序。程序语言可选C或C++。

#include <iostream>
#include <cstdio>
#include <malloc.h>
using namespace std;
 
int main(){
    //输入n和待排序数组 
    int n;
    cin>>n;
    int *input=(int*)malloc(sizeof(int)*n);
    for(int i=0;i<n;i++){
        cin>>input[i];
    }
    
    //选择排序
    for(int i=0;i<n-1;i++){
        int index=i;
        for(int j=i+1;j<n;j++){
            if(input[j]<input[index]){
                index=j;//record the min index
            }
        }
        //交换记录 
        if(index!=i){
            int t=input[i];
            input[i]=input[index];
            input[index]=t;
        }
    }
    
    //输出结果 
    for(int i=0;i<n;i++){
        if(i==n-1){
            cout<<input[i];//输出样式注意点 
        }
        else{
            cout<<input[i]<<" ";
        }
    }
    return 0;
}

最近点对

【问题描述】输入若干个二维点,横纵坐标分别依次存储于数组x, y中,请合理设计算法求出最近点对,并输出这个最近的距离。

【填写说明】

请阅读上下文并在空格处填入缺失代码。

最后距离的开方计算保留小数点后三位即可,提示:可采用二分查找实现。

【评分标准】结果正确的情况下结合计算时间排行获得相应分数。

#include<iostream>
using namespace std;
 
float ClosestPoints(float x[ ], float y[ ], int n);
int main()
{
    int n;
    float x[1000], y[1000];
 
    cin>>n;
    for(int i=0;i<n;i++)
    {
        cin>>x[i];
    }
    for(int i=0;i<n;i++)
    {
        cin>>y[i];
    }
    float min_distance = ClosestPoints(x, y, n);
    cout<<min_distance;
    return 0;
}
 
float ClosestPoints(float x[ ], float y[ ], int n)
{
//涓ゆ寰幆鎵炬渶灏忚窛绂?
    float d=(x[0]-x[1])*(x[0]-x[1])+(y[0]-y[1])*(y[0]-y[1]);
    for(int i=0;i<n-1;i++){
        for(int j=i+1;j<n;j++){
            if(d>(x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j])){
                d=(x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]);
            }
        }
    }
    
    float low,high,mid,e=0.0001;
    //distance<1 寮€鏂圭粨鏋滃湪0~1涔嬮棿 鍚﹀垯缁撴灉鍦?~d 
    if(d<1){
        low=d;
        high=1;
    }
    else{
        low=1;
        high=d;
    }
    
    //寮€鏂?
    while(high-low>e){
        mid=(high+low)/2;
        if(mid*mid>d){
            high=mid;
        }
        else{
            low=mid;
        }
    }
    
    mid*=1000;
    int ret=(int) mid;
    mid=(float)ret/1000;
    
    return mid;
}

 4:

分治法排序

选择一种本章分治法中介绍的算法,对整数数组进行排序。

#include <iostream>
#include <fstream>
using namespace std;
 
int length = 100000;
int arr[100000+1];
 
//start1
void swap(int *a,int *b){
    int *temp=a;
    a=b;
    b=temp;
}
 
void QuickSort(int a[],int start,int end){
    int newstart=start,newend=end;
    int mid=(start+end)/2;
    int temp=a[mid];
    //鍙湁涓€涓厓绱?or 涓婃鎺掑簭鍦ㄨ竟鐣?
    if(mid==end || start>end){
        return;
    }
    if(mid==start){
        if(a[start]>a[end]){
            swap(a[start],a[end]);
        }
        return;
    }
    while(end>start){
        while(a[start]<temp){
            start++;
        }
        while(end>=start && a[end]>=temp){
            end--;
        }
        if(end>start){
            swap(a[start],a[end]);
            if(mid==start){
                mid=end;
            }
        }
        else{
            swap(a[mid],a[start]);
            mid=start;
        }
    }
    QuickSort(a,newstart,mid-1);//宸︿晶鍫?
    QuickSort(a,mid+1,newend);//鍙充晶鍫?
}
//end1 
 
int main()
{
    ifstream inFile("array.dat", ios::in | ios::binary);
    if (!inFile) {
        cout << "error" << endl;
        return 0;
    }
    for (int i = 1; i <= length; i++)
    {
        inFile.read((char *)&arr[i], sizeof(int));
    }
    inFile.close();
 
//start2
QuickSort(arr,0,length);
//end2
 
    ofstream outFile("sorted.dat", ios::out | ios::binary);
    for (int i = 1; i <= length; i++)
    {            
        outFile.write((char*)&arr[i], sizeof(int));
    }
    outFile.close();
 
    return 0;
}

5:

减治法求解选择问题

设无序序列T =(r1, r2, …, rn),T 的第k(1≤k≤n)小元素定义为T按升序排列后在第k个位置上的元素。

给定序列T和整数k,寻找T的第k小元素的问题称为选择问题。

采用减治法设计一个高效的算法求解任意选择问题。

代码中数组下标从1开始,第0位置空缺。

#include <iostream>
#include <fstream>
using namespace std;
 
int length = 100000;
int arr[100000 + 1];
 
int Partition(int r[],int low,int high){
    int i=low,j=high;
    while(i<j){
        while(i<j&&r[i]<=r[j])
            j--;
        if(i<j){
            int temp=r[i];
            r[i]=r[j];
            r[j]=temp;
            i++;
        }
        while(i<j&&r[i]<=r[j])
            i++;
        if(i<j){
            int temp=r[i];
            r[i]=r[j];
            r[j]=temp;
        }
    }
    return i;
}
 
int SelectMinK(int r[],int low,int high,int k){
    int s;
    s=Partition(r,low,high);
    if(s==k)
        return r[s];
    if(s>k)
        return SelectMinK(r,low,s-1,k);
    else
        return SelectMinK(r,s+1,high,k);
}
 
int main()
{
    ifstream inFile("input.dat", ios::in | ios::binary);
    if (!inFile) {
        cout << "error" << endl;
        return 0;
    }
 
    int k = 0;
    inFile.read((char *)&k, sizeof(int));
 
    for (int i = 1; i <= length; i++)
    {
        inFile.read((char *)&arr[i], sizeof(int));
    }
    inFile.close();
 
    int v = 0; //Put the result in this variable.
    SelectMinK(arr,0,length,k);  
     v = arr[k];
    ofstream outFile("output.dat", ios::out | ios::binary);            
    outFile.write((char*)&v, sizeof(int));
    outFile.close();
 
    return 0;
}

6:

【问题描述】

给定一个序列,如果其中有些元素(也可能没有)被省略,则我们可以得到该序列的一个子序列。给定一个序列X = <x1...xn> ,另一个序列Z满足条件,存在严格递增索引序列I=<i1...ik>,使得对于所有j = 1,2,…,k, 有xij=zj,则称Z= <z1...zk>是X的子序列。

例如,Z = <a, b, f, c>是X = <a, b, c, f, b, c>的子序列。

给定两个序列X和Y,问题是求出X和Y的最大长度公共子序列的长度。

【输入形式】

两个给定字符串

【输出形式】

两个序列最大长度公共子序列的长度。

【样例输入】

abcfbc abfcab
【样例输出】

4

#include <iostream>
#include <cstring>
#include <cstdio>
#include <cstdlib>
using namespace std;
 
 
char str1[1000],str2[1000];
 
//定义取最大值函数 
int fmax(int a, int b) {
	if(a > b) return a;
	else return b;
}
 
//求公共子序列函数 
int longestCommonSubsequence(char* text1, char* text2) {
    int m = strlen(text1), n = strlen(text2);
    int dp[m + 1][n + 1];
    memset(dp, 0, sizeof(dp));
    for (int i = 1; i <= m; i++) {
        char c1 = text1[i - 1];
        for (int j = 1; j <= n; j++) {
            char c2 = text2[j - 1];
            if (c1 == c2) {
                dp[i][j] = dp[i - 1][j - 1] + 1;
            } 
			else {
                dp[i][j] = fmax(dp[i - 1][j], dp[i][j - 1]);
            }
        }
    }
    return dp[m][n];
}
 
//主函数 
int main(){
	scanf("%s %s",&str1,&str2);
	printf("%d",longestCommonSubsequence(str1,str2));
	return 0;
}

动态规划求最长递增子序列

 输出最长递增子序列的长度

#include  <iostream>
#include  <fstream>
using  namespace  std;
 
int length=100;
int arr[100];
 
int IncreaseOrder(int a[], int  n);
 
int main(){
    for(int i = 0; i < length; i++){
        cin >> arr[i];
    }
 
    int result = IncreaseOrder(arr, length);
 
    cout << result;
    return 0;
}
 
int inline fmax(int a,int b){
	return (a>b ? a : b);
}
 
#include <malloc.h>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cstdlib>
int IncreaseOrder(int a[],int n){
	int *dp=(int*)malloc(sizeof(int)*n),ret=0,max=0;
	memset(dp,0,sizeof(dp));
	dp[1]=1;
	for(int i=2;i<=n;i++){
		max=0;
		for(int j=1;j<i;j++){
			if(a[i-1]>a[j-1]){
				max=fmax(max,dp[j]);
			}
		}
		dp[i]=max+1;
		ret=fmax(ret,dp[i]);
	}
	return ret;
}
 
/*
int IncreaseOrder(int a[],int n){
	int dp[n+1];
    for(int i=0;i<=n;i++){
        dp[i] = 1;
    }
    int res=1;
    for(int i=1;i<=n;i++){
        for(int j=1;j<i;j++){
            if(a[i-1]>a[j-1]){
                dp[i]=fmax(dp[i],dp[j]+1);
                res=fmax(res,dp[i]);
            }
        }
    }
    return res;
}
*/

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
培养基优化 培养基优化,是指面对特定的微生物,通过实验手段配比和筛选找到一种最适合其生长及发酵的培养基,在原来的基础上提高发酵产物的产量,以期达到生产最大发酵产物的目的。发酵培养基的优化在微生物产业化生产中举足轻重,是从实验室到工业生产的必要环节。能否设计出一个好的发酵培养基,是一个发酵产品工业化成功中非常重要的一步。 目录 1试验设计 单因素法 正交实验设计 均匀设计 全因子实验设计 部分因子设计 Plackett-Burman设计 中心组合设计 Box–Behnken设计 2技术实验统计 响应曲面分析法 改进单纯形优化法 遗传算法 培养基优化试验设计 在工业化发酵生产中,发酵培养基的设计是十分重要的,因为培养基的成分对产物浓度、菌体生长都有重要的影响。实验设计方法发展至今可供人们根据实验需要来选择的余地也很大。 培养基优化单因素法 单因素方法(One at a time)的基本原理是保持培养基中其他所有组分的浓度不变,每次只研究一个组分的不同水平对发酵性能的影响。这种策略的优点是简单、容易,结果很明了,培养基组分的个体效应从图表上很明显地看出来,而不需要统计分析。这种策略的主要缺点是:忽略了组分间的交互作用,可能会完全丢失最适宜的条件;不能考察因素的主次关系;当考察的实验因素较多时,需要大量的实验和较长的实验周期。但由于它的容易和方便,单因素方法一直以来都是培养基组分优化的最流行的选择之一。 培养基优化正交实验设计 试验优化设计方案全文共3页,当前为第1页。正交设计(Orthogonal design)就是从"均匀分散、整齐可比"的角度出发,是以拉丁方理论和群论为基础,用正交表来安排少量的试验,从多个因素中分析出哪些是主要的,哪些是次要的,以及它们对实验的影响规律,从而找出较优的工艺条件。石炳兴等利用正交实验设计优化了新型抗生素AGPM 的发酵培养基,结果在优化后的培养基上单位发酵液的活性比初始培养基提高了18.9倍。正交实验不能在给出的整个区域上找到因素和响应值之间的一个明确的函数表达式即回归方程,从而无法找到整个区域上因素的最佳组合和响应值的最优值。而且对于多因素多水平试验,仍需要做大量的试验,实施起来比较困难。 试验优化设计方案全文共3页,当前为第1页。 培养基优化均匀设计 均匀设计 (Uniform design)是我国数学家方开泰等独创的将数论与多元统计相结合而建立起来的一种试验方法。这一成果已在我国许多行业中取得了重大成果。均匀设计最适合于多因素多水平试验,可使试验处理数目减小到最小程度,仅等于因素水平个数。虽然均匀设计节省了大量的试验处理,但仍能反映事物变化的主要规律。 培养基优化全因子实验设计 在全因子设计(Full factorial design)中各因素的不同水平间的各种组合都将被实验。全因子的全面性导致需要大量的试验次数。一般利用全因子设计对培养基进行优化实验都为两水平,是能反映因素间交互作用(排斥或协同效应)的最小设计。全因子试验次数的简单算法为(以两因素为例):两因素设计表示为 a ×b,第一个因素研究为a个水平,第二个因素为b个水平。Thiel等试验了两个因素:7个菌株在8种培养基上,利用7 ×8(56个不同重复)。Prapulla等试验了三个因素:碳源(糖蜜4%,6%,8%,10%,12%),氮源(NH4NO3 0g/L、0.13g/L、0.26g/L、0.39g/L、0.52g/L、)和接种量(10%、20%),利用5 × 5 × 2设计(50个不同重复)。 培养基优化部分因子设计 当全因子设计(fractional factorial design)所需试验次数实际不可行时部分重复因子设计是一个很好的选择。在培养基优化中经常利用二水平部分因子设计,但也有特殊情况,如Silveira 等试验了11种培养基成分,每成分三水平,仅做了27组实验,只是311全因子设计177147组当中的很小一部分。两水平部分因子设计表示为:2n–k,n是因子数目,1/2k 是实施全因子设计的分数。这些符号告诉你需要多少次试验。虽然通常部分因子设计没有提供因素的交互作用,但它的效果比单因素试验更好。 培养基优化Plackett-Burman设计 由Plackett 和Burman (Plackett-Burman design)提出,这类设计是两水平部分因子试验,适用于从众多的考察因素中快速、有效的筛选出最为重要的几个因素,供进一步详细研究用。理论上讲PB试验应该应用在因子存在累加效应,没有交互作用—因子的效应可以被其他因子所提高或削弱的试验上。实际上,倘若因子水平选择恰当,设计可以得到有用的结果。Castro等利用PB试验对培养基中的20种组分仅进行了24次试验,使γ-干扰素的产量提高了近45%。 培养基优化

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

MorleyOlsen

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值