uva11512

25 篇文章 0 订阅
3 篇文章 0 订阅
#include <iostream>
#include <vector>
#include <set>
#include <cstdlib>
#include <algorithm>
#include <map>
#include <string.h>
#include <stdio.h>
//把字符串变成4进制;二分法找到最长的长度,再在重复2次及以上的子基因中遍历找最短的,并在此过程中累加最短子基因的个数

using namespace std;
int max_len;
string min_s;
int cou_s;
string str;
vector<int> str_int;
map<int,set<string> > len_str;
vector<int> hash_;
vector<int> wight;
void get_wight()
{
    wight.clear();
    wight.push_back(1);
    int str_len=str.length();
    for(int i=1; i<=1005; i++)
        wight.push_back((wight[i-1]*4)%100000007);//debug半天……
}
void strintoint()
{
    cin>>str;
    int len=str.length();
    str_int.clear();
    for(int i=0; i<len; i++)
    {
        if(str[i]=='A')
            str_int.push_back(0);
        else if(str[i]=='T')
            str_int.push_back(1);
        else if(str[i]=='C')
            str_int.push_back(2);
        else
            str_int.push_back(3);
    }
}
void get_hash_value(int len)
{
    hash_.clear();
    int tmp=0;
    for(int i=0; i<len; i++)
        tmp=(tmp*4+str_int[i])%100000007;
    hash_.push_back(tmp);
    int str_len=str.length();
    for(int i=len; i<str_len; i++)
    {
        tmp=((tmp-str_int[i-len]*wight[len-1]+(100000007 << 2))*4+str_int[i])%100000007;
        hash_.push_back(tmp);
    }
}
bool repeat(int len)
{
    get_hash_value(len);
    len_str.clear();
    int len_=hash_.size();
    for(int i=0; i<len_; i++)
    {
        string s=str.substr(i,len);
        if(!len_str[hash_[i]].count(s))
            len_str[hash_[i]].insert(s);
        else
            return true;
    }
    return false;
}
int binarySearch(int left,int right)//1到n不是均匀的,有可能n/2符合repeat,但是n/2+1就不符合了……所以以前那种模板就不行了……
{
    if(left > right)
    {
        return 0;
    }
    else
    {
        int mid = (left + right) >> 1;
        if(repeat(mid))
            return max(mid, binarySearch(mid+1, right));
        else
            return binarySearch(left, mid-1);
    }
}
void find_ans_s()
{
    get_hash_value(max_len);
    len_str.clear();
    int len_=hash_.size();
    min_s="aa";
    cou_s=0;
    for(int i=0; i<len_; i++)
    {
        string s=str.substr(i,max_len);
        if(!len_str[hash_[i]].count(s))
            len_str[hash_[i]].insert(s);
        else if(s<min_s)
        {
            cou_s=2;
            min_s=s;
        }
        else if(s==min_s)
            cou_s++;
    }
}
void out_ans()
{
    max_len=binarySearch(1,str.length()-1);
    if(max_len==0) cout<<"No repetitions found!"<<endl;
    else
    {
        find_ans_s();
        cout<<min_s<<" "<<cou_s<<endl;
    }
}
int main()
{
    //freopen("debug\\in.txt","r",stdin);
   // freopen("debug\\out.txt","w",stdout);
    int cases;
    cin>>cases;
    get_wight();
    while(cases--)
    {
        strintoint();

        out_ans();
    }
    return 0;
}
/*
1
GATTACA
*/

很多数据都对了,结果一定是在大数据上出错,一些计算式要注意……

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值