(poj 2588 )Genetic Code

来源:互联网 发布:java base64编码解码 编辑:程序博客网 时间:2024/06/03 20:18

Special Judge
Problem Description
The connections between mathematics and biology are complicated. Most of the time they do not run along nice-looking links that merrily join at first glance, but they are abstract and not always easily established. Lake Vostok - about 14000 square kilometers large, up to 650 meters deep, and covered by 3743 meters of ice - was recently discovered on the Antarctic continent. The lake remained under conditions of high pressure and no sunlight for several millions of years. It is believed that ordinary life has evolved to a more efficient form using a genetic code composed of only three bases (the current state of ignorance proclaims the four bases adenine, cytosine, guanine, and thymine). Until reasonable names are found, the three bases will be abbreviated as N, O, and P.
Moreover, the genome is single-stranded and directed, i.e., we may see it as a sequence over the alphabet {N,O,P}. Unless risking instability, it is necessary that the genome is a Thue-sequence, due to the Norwegian mathematician A. Thue (1863-1922). Define a subsegment of a sequence to be a connected subsequence, and call two subsegments adjacent if one follows immediately after the other in the sequence. A Thue-sequence is a sequence where no adjacent subsegments are equal. For example, NOPNO is and NOPNPNO is not a Thue-sequence, so that the first may be a genome whereas the second may not.
To be able to simulate experiments with the new genomes, you are asked to generate genomes of certain lengths.

Input
The input contains several test cases. Each test case consists of an integer n. You may assume that 1<=n<=5000. The last test case is followed by a zero.

Output
For each test case specified by n output on a single line any genome of length n. If no genome of length n exists, output a blank line instead.

Sample Input
1
2
10
20
0

Sample Output
N
NO
NONPNOPNPO
NONPNOPNPONOPNONPNOP

Source
University of Ulm Local Contest 2003

题目大意:由’N’ , ‘O’, ‘P’组成,求一个长度为n(不大于5000的串),串中没有相邻的重复子串。
1.一种思路:来源于 上一篇 困难的串。 两题其实是一样的题,判断当前串的后缀
AC代码:
1172ms 1143B

#include<cstdio>#include<algorithm>#include<cstring>using namespace std;const int N=5005;char cd[]="NOP",ans[N];int n,flag,cnt;int dfs(int cur){    if(cur==n)    {        flag=1;///找到合理的串的标记        for(int i=0; i<cur; i++)            putchar(ans[i]);        printf("\n");        return 0;    }    if(!flag)    {        for(int i=0; i<3; i++)        {            ans[cur]=cd[i];///ans储存基因编码            int flag2=1;///flag2=1是没有重复子串的标记            for(int j=1; 2*j<=cur+1; j++) ///判断串中是否有重复子串            {                int xd=1;                for(int k=0; k<j; k++)                    if(ans[cur-k]!=ans[cur-k-j])                    {                        xd=0;                        break;                    }                if(xd)///后一半等于前一半,不合法,跳出循环                {                    flag2=0;                    break;                }            }            if(flag2)            {                dfs(cur+1);///写cur+1是便于回溯                if(flag) return 0;///找到合理串返回            }        }    }    return 1;///返回上一级调用}int main(){    while(~scanf("%d",&n)&&n)    {        flag=0;        dfs(0);        if(!flag) printf("\n");    }    return 0;}

2.记忆化搜索打表
AC代码:94ms 850B

#include<cstdio>#include<cstring>using namespace std;const int N=5005;int ans[N],flag;bool check(int len)///检查当前串是否合法{    for(int i=1; i*2<=len+1; i++)    {        int xd=1;        for(int j=0; j<i; j++)            if(ans[len-j]!=ans[len-i-j])            {                xd=0;                break;            }        if(xd)///若有连续重复子串            return false;    }    return true;///合法}void dfs(int cnt){    if(cnt>N-4)///已经全部找到    {        flag=1;        return ;    }    for(int i=0; i<3&&!flag; i++)    {        ans[cnt]=i;        if(check(cnt))            dfs(cnt+1);    }}int main(){    int n;    flag=0;    dfs(0);    while(~scanf("%d",&n))    {        for(int i=0; i<n; i++)            if(ans[i]==0) putchar('N');            else if(ans[i]==1) putchar('O');            else putchar('P');        printf("\n");    }    return 0;}
原创粉丝点击