2012蓝桥杯C组本科决赛答案

题目:

脱氧核糖核酸即常说的DNA,是一类带有遗传信息的生物大分子。它由4种主要的脱氧核苷酸(dAMP、dGMP、dCMT和dTMP)通过磷酸二酯键连接而成。这4种核苷酸可以分别记为:A、G、C、T。

 

    DNA携带的遗传信息可以用形如:AGGTCGACTCCA.... 的串来表示。DNA在转录复制的过程中可能会发生随机的偏差,这才最终造就了生物的多样性。

 

    为了简化问题,我们假设,DNA在复制的时候可能出现的偏差是(理论上,对每个碱基被复制时,都可能出现偏差):

 

  1. 漏掉某个脱氧核苷酸。例如把 AGGT 复制成为:AGT

 

    2. 错码,例如把 AGGT 复制成了:AGCT

 

    3. 重码,例如把 AGGT 复制成了:AAGGT

    如果某DNA串a,最少要经过 n 次出错,才能变为DNA串b,则称这两个DNA串的距离为 n。

 

    例如:AGGTCATATTCC 与 CGGTCATATTC 的距离为 2

 

    你的任务是:编写程序,找到两个DNA串的距离。

 

 

【输入、输出格式要求】

 

    用户先输入整数n(n<100),表示接下来有2n行数据。

 

    接下来输入的2n行每2行表示一组要比对的DNA。(每行数据长度<10000)

 

    程序则输出n行,表示这n组DNA的距离。

 

    例如:用户输入:

3

AGCTAAGGCCTT

AGCTAAGGCCT

AGCTAAGGCCTT

AGGCTAAGGCCTT

AGCTAAGGCCTT

AGCTTAAGGCTT

 

    则程序应输出:

1

1

2

 我的解答如下:

动态方程:如果str1[i]==str2[j],dp[i][j]=Min(dp[i-1][j-1],dp[i][j-1]+1,dp[i-1][j]+1);

     如果str1[i]!=str2[j],dp[i][j]=Min(dp[i-1][j],dp[i][j-1],dp[i-1][j-1])+1;

前段时间贴的代码有错,现在改过来了

#include<iostream>

#include<cstdio>

#include<cstring>

using namespace std;

int dp[2][10010];

int Min(int a,int b,int c)

{

    int temp;

    temp=a<b?a:b;

    return temp<c?temp:c;

}

void init()

{

    int i,j;

    memset(dp,0,sizeof(dp));

    for(i=0;i<=10000;i++)

      dp[0][i]=i;

}

int main()

{

    char str1[10010],str2[10010];

    int i,j;

    int T;

    scanf("%d",&T);

    while(T--)

    {

        init();

        scanf("%s%s",&str1,&str2);

        int l1,l2;

        l1=strlen(str1);

        l2=strlen(str2);

        int now=0,pre=1;

        for(i=0;i<l1;i++)//求最长公共子序列的思想。

        {

            now^=1;

            pre^=1;

            dp[now][0]=i+1;

            for(j=0;j<l2;j++)

            {    if(str1[i]==str2[j])

                    dp[now][j+1]=Min(dp[pre][j],dp[pre][j+1]+1,dp[now][j]+1);

                else

                    dp[now][j+1]=Min(dp[pre][j+1],dp[now][j],dp[pre][j])+1;

            }

        }

        printf("%d\n",dp[now][l2]);

    }

    return 0;

}

 

 

最后一题解答:

#include<iostream>

#include<cstdio>

#include<cstring>

using namespace std;

int map[7][7];

int num[7][7];

char H[6];

int ff=0;

int n=1;

void dfs(int x,int y)

{

    int i,j;

    if(x==6)

    {

        ff=1;

        cout<<n++<<endl;

        for(i=0;i<=5;i++)

        {    for(j=0;j<=5;j++)

            {

                printf("%c",H[map[i][j]]);

            }

        printf("\n");

        }

    return ;

    }

    int div=num[x][y];

    int f=0;

    if(map[x][y]==-1)

    for(i=0;i<=5;i++)

    {

        f=0;

        for(j=0;j<6;j++)

            if(map[j][y]==i)

            {f=1;break;}

        for(j=0;j<6;j++)

            if(map[x][j]==i)

            {f=1;break;}

        for(j=0;j<=5;j++)

            for(int k=0;k<=5;k++)

                if(num[j][k]==div&&map[j][k]==i)

                {f=1;break;}

        if(f)

            continue;

        map[x][y]=i;

        if(y<=4)

            dfs(x,y+1);

        else

            dfs(x+1,0);

        map[x][y]=-1;

    }

    else

    {

        if(y<=4)

            dfs(x,y+1);

        else

            dfs(x+1,0);

    }

    return ;

}

int pre[10010],now[10010];

void init()

{

    memset(map,-1,sizeof(map));

    memset(num,-1,sizeof(num));

    H[0]='A';

    H[1]='B';

    H[2]='C';

    H[3]='D';

    H[4]='E';

    H[5]='F';

    ff=0;

}

int main()

{

    int i,j;

    int T;

    char str[7];

    init();

    for(i=0;i<=5;i++)

    {

        scanf("%s",&str);

        for(j=0;j<=5;j++)

            num[i][j]=str[j]-'0';

    }

    //cout<<"ok"<<endl;

    scanf("%d",&T);

    while(T--)

    {

        scanf("%s",&str);

        map[str[0]-'0'][str[1]-'0']=str[2]-'A';

    }

    //cout<<"ok"<<endl;

    dfs(0,0);

    if(!ff)

        printf("无解\n");

    return 0;

}

 

你可能感兴趣的:(2012)