Viruses are usually bad for your health. How about ghting them with... other viruses? In this problem,

you need to nd out how to synthesize such good viruses.

We have prepared for you a set of strings of the letters A, G, T and C. They correspond to the

DNA nucleotide sequences of viruses that we want to synthesize, using the following operations:

• Adding a nucleotide either to the beginning or the end of the existing sequence.

• Replicating the sequence, reversing the copied piece, and gluing it either to the beginning or to

the end of the original (so that e.g., AGTC can become AGTCCTGA or CTGAAGTC).

We're concerned about efficiency, since we have very many such sequences, some of them very long.

Find a way to synthesize them in a minimum number of operations.

Input

The rst line of input contains the number of test cases T. The descriptions of the test cases follow:

Each test case consists of a single line containing a non-empty string. The string uses only the

capital letters `A', `C', `G' and `T' and is not longer than 100 000 characters.

Output

For each test case, output a single line containing the minimum total number of operations necessary

to construct the given sequence.

Sample Input

4

AAAA

AGCTTGCA

AAGGGGAAGGGGAA

AAACAGTCCTGACAAAAAAAAAAAAC

Sample Output

3

8

6

18

参考大牛的博客

http://www.cnblogs.com/clrs97/p/4700658.html

#include <iostream>
#include <string.h>
#include <algorithm>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <map> using namespace std;
typedef long long int LL;
const int maxn=1e5+5;
map<char,int> m;
int n;
char str[maxn];
int f[maxn];
struct Tree
{
int next[maxn][4];
int fail[maxn];
int train[maxn];
int len[maxn];
int num[maxn];
int cnt[maxn];
int s[maxn];
int last;
int p;
int n;
int new_node(int x)
{
memset(next[p],0,sizeof(next[p]));
len[p]=x;
return p++;
}
void init()
{
p=0;
new_node(0);
new_node(-1);
last=0;n=0;
s[0]=-1;
fail[0]=1;
}
int get_fail(int x)
{
while(s[n-len[x]-1]!=s[n])
x=fail[x];
return x;
}
int get_fail2(int x,int pos)
{
while(s[n-len[x]-1]!=s[n]||(len[x]+2)*2>len[pos])
x=fail[x];
return x;
}
void add(char xx)
{
int x=m[xx];
s[++n]=x;
int cur=get_fail(last);
if(!(last=next[cur][x]))
{
int now=new_node(len[cur]+2);
fail[now]=next[get_fail(fail[cur])][x];
if(len[now]<=2)
train[now]=fail[now];
else
train[now]=next[get_fail2(train[cur],now)][x]; next[cur][x]=now;
last=now;
}
}
}tree;
int ans;
int q[maxn];
int rear,head;
int main()
{
int t;
scanf("%d",&t);
m['A']=0;m['C']=1;m['G']=2;m['T']=3;
while(t--)
{
scanf("%s",str);
int len=strlen(str);
tree.init();
ans=len;
for(int i=0;i<len;i++)
{
tree.add(str[i]);
}
memset(f,0,sizeof(f));
for(int i=2;i<tree.p;i++)
{
if(tree.len[i]&1)
f[i]=tree.len[i];
}
f[0]=1;
q[0]=0;
head=0;rear=1;
int x,y;
while(head<rear)
{
x=q[head++];
for(int i=0;i<4;i++)
{
if(tree.next[x][i])
{
y=tree.next[x][i];
f[y]=f[x]+1;
f[y]=min(f[y],tree.len[y]/2-tree.len[tree.train[y]]+f[tree.train[y]]+1);
ans=min(ans,len-tree.len[y]+f[y]);
q[rear++]=y;
} }
}
printf("%d\n",ans);
}
return 0;
}

最新文章

  1. C# 反射之调用方法谈
  2. Java 编程入门(词汇表)
  3. EWM ODO清理功能
  4. 关于webstorm的使用编码的问题
  5. [C和指针] rearrange.c
  6. 第 1 章 策略模式【Strategy Pattern】
  7. pyqt下拉菜单和打开指定的内容(或者exe,doc,ppt,url等内容)
  8. 仿CSDN Blog返回页面顶部功能
  9. sql日期
  10. SQL基础-----DML语句
  11. CPP笔记_函数返回局部变量
  12. NSE: known a priori estimate
  13. LOJ 6277:数列分块入门 1(分块入门)
  14. [Android Pro] 开发一流的 Android SDK:Fabric SDK 的创建经验
  15. 利用CNN进行流量识别 本质上就是将流量视作一个图像
  16. 1055. [HAOI2008]玩具取名【区间DP】
  17. debian下配置双核cpu
  18. cocos2dx 3.3 getParentToNodeTransform bug
  19. Python 使用正则表达式匹配电子邮箱
  20. iOS 屏幕录制功能

热门文章

  1. 为什么会找不到D层文件?
  2. atitit.spring hibernate的事务机制 spring不能保存对象的解决
  3. Atitit. 解释器模式框架选型 and应用场景attilax总结 oao
  4. IOS委托,实现两个UIView相互传值
  5. Spring学习11-Spring使用proxool连接池 管理数据源
  6. vue的路由使用
  7. RCC—使用 HSE/HSI 配置时钟 ---时钟树
  8. SpringMVC之学习(1)
  9. Scala中List(Map1,Map2,Map3 ....) 转成一个Map
  10. php 判断查询结果是否为空