UVALive 6933 Virus synthesis(回文树)
2016-05-31 08:46
387 查看
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
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 ) x=fail[x]; return x; } int get_fail2(int x,int pos) { while(s[n-len[x]-1]!=s ||(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; }
相关文章推荐
- 复习
- popen + top 获取系统信息
- USACO Section 1.3
- Android UI Libs之android-viewbadger
- Android官方开发文档Training系列课程中文版:动画视图之场景创建
- TCP/UDP简单介绍及JavaSocket的使用
- 最清晰细致的教程!一步步教你打造Win7+CentOS双系统
- 转载 -节选傅盛的演讲
- 读书笔记之《深入浅出Node.js》(3)
- 高吞吐高并发Java NIO服务的架构(NIO架构及应用之一)
- c++ 17介绍
- c++ 17介绍
- 【bzoj4530】【BJOI2014】【大融合】【dfs序+线段树合并+并查集】
- sdau三 1023
- C++14介绍
- OS 获取本地视频的缩略图
- c++11介绍
- C++14介绍
- c++11介绍
- ubuntu 命令记录