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