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;
}

 

posted @ 2013-07-01 19:24  fangguo  阅读(292)  评论(0编辑  收藏  举报