HDU2144Evolution(并查集+暴力或LCS)

Evolution

Time Limit: 20000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 598    Accepted Submission(s): 143


Problem Description
  Every kind of living creatures has a kind of DNA. The nucleotide bases from which DNA is built are A (adenine), C (cytosine), G (guanine), and T (thymine). Sometimes if two DNA of two living creatures have the same substring, and the length is beyond a certain percentage of the whole length, we many consider whether the two living creatures have the same ancestor. And we can separate them into a certain species temporarily for our research, and we say the two living creatures are similar Make sure if A is similar with B, and B is similar with C, but C is not similar with A, we also separate A, B and C into a kind, for during the evolution, there happens aberrance.
Now we have some kinds of living creatures and their DNA, just tell us how many kinds of living creatures we can separate.
 

Input
  There are a lot of cases. In each case, in the first line there are two numbers N and P. N means the number of kinds of living creatures. If two DNA are similar, there exist a substring, and its length is beyond the percentage of any DNA of the two, and P is just the percentage. And 1<=N<=100, and 1<=P<100 (P is 100, which means two DNA are similar if and only if they are the same, so we make sure P is smaller than 100). The length of each DNA won't exceed 100.
 

Output
  For each case, just print how many kinds living creatures we can separate.
 

Sample Input
  
  
3 10.0 AAA AA CCC
 

Sample Output
  
  
Case 1: 2
 
#include<stdio.h>
#include<string.h>
const int N = 105;

int fath[N],ins[N],n;

void init()
{
    for(int i=0;i<n;i++)
        fath[i]=i,ins[i]=0;
}
int findfath(int x)
{
    if(x!=fath[x])
        fath[x]=findfath(fath[x]);
    return fath[x];
}
void setfath(int x,int y)
{
    x=findfath(x);
    y=findfath(y);
    fath[x]=y;
}
int main()
{
    double P;
    int c=0,len[N];
    char DNA[N][N];
    while(scanf("%d%lf",&n,&P)>0)
    {
        for(int i=0;i<n;i++)
        {
             scanf("%s",DNA[i]);
             len[i]=strlen(DNA[i]);
        }

        init();
        for(int i=0; i<n; i++)
        for(int j=i+1; j<n; j++)
        {
           int maxlen=0,flag=0;
            for(int ti=0;ti<len[i]&&maxlen<len[i]-ti;ti++)
            {
                for(int tj=0;tj<len[j]&&maxlen<len[j]-tj;tj++)
                {
                    int ii,jj;
                    for( ii=ti,jj=tj; ii<len[i]&&jj<len[j]; ii++,jj++)
                    if(DNA[i][ii]!=DNA[j][jj])
                    {
                       break;
                    }
                    if(ii-ti>maxlen)
                        maxlen=ii-ti;
                    if(100*maxlen/(len[i]*1.0)>P&&100*(maxlen/(len[j]*1.0))>P)
                            setfath(i,j),flag=1;
                    if(flag)break;
                }
                if(flag)break;
            }
        }
        int k=0;
        for(int i=0;i<n;i++)
            if(fath[i]==i)
            k++;
        printf("Case %d:\n%d\n",++c,k);
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值