北京林业大学“计蒜客”杯程序设计竞赛 D. A letter from Chensg

题目回忆版:
原题POJ 3080 Blue Jeans 求多个字符串的最长公共子序列。
【思路】:
参考:POJ 3080 KMP||暴力
暴力思想很简单:

开二维DNA[][]保存所有DNA序列

1、 以DNA[0]为母版,顺次截取60个长度length=1的子串dna[],检查其他DNA[i]是否都有子串dna,若是则把dna[]复制到obj[],否则枚举下一个长度length的子串;若obj与新的dna等长,则比较两者字典序,当dna字典序小时,复制到obj

2、 第1步循环60次后length+1。

顺次截取59个长度length=2的子串dna[],重复1的操作更新obj。。

3、 第2步循环59次后length+1。

顺次截取58个长度length=3的子串dna[],继续。。

………..

60、第59步循环2次后length+1。

顺次截取1个长度length=60的子串dna[],继续重复操作更新obj。。

61、输出obj

【代码】:

//Memory Time 
//248K   16MS 

#include<iostream>
#include<string.h>
using namespace std;

const int len=60;

int main(int i,int j)
{
    int test;
    cin>>test;
    for(int t=1;t<=test;t++)
    {
        int n;  //DNA个数
        cin>>n;
        char** DNA=new char*[n];
        for(int p=0;p<n;p++)
        {
            DNA[p]=new char[len+1];
            cin>>DNA[p];
        }

        char obj[len+1];  //所有DNA的公共串
        int StrLen=0;    //最长公共串长度
        int length=1;    //当前枚举的公共串长度

        for(i=0;;i++)  //枚举公共串dna[]
        {
            /*截取DNA[0][]中以pi为起点,长度为length的子串dna[]*/
            char dna[len+1];
            int pi=i;
            if(pi+length>len)
            {
                length++;
                i=-1;
                if(length>len)
                    break;
                continue;
            }
            for(j=0;j<length;j++)
                dna[j]=DNA[0][pi++];
            dna[j]='\0';

            /*检查其他DNA[][]是否都存在字符串dna[]*/
            bool flag=true;
            for(int k=1;k<n;k++)
                if(!strstr(DNA[k],dna))  //存在一个DNA不含有dna[]
                {
                    flag=false;
                    break;
                }

            /*确认最大公共串*/
            if(flag)
            {
                if(StrLen<length)
                {
                    StrLen=length;
                    strcpy(obj,dna);    
                }
                else if(StrLen==length)
                {
                    if(strcmp(obj,dna)>0)  //存在相同长度的公共串时,取最小字典序的串
                        strcpy(obj,dna);
                }
            }
        }

        if(StrLen<3)
            cout<<"no significant commonalities"<<endl;
        else
            cout<<obj<<endl;

        delete DNA;
    }
    return 0;
}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值