hdu 1560 DNA sequence(搜索)
http://acm.hdu.edu.cn/showproblem.php?pid=1560
DNA sequence
Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 732 Accepted Submission(s): 356
Problem Description
The twenty-first century is a biology-technology developing century. We know that a gene is made of DNA. The nucleotide bases from which DNA is built are A(adenine), C(cytosine), G(guanine), and T(thymine). Finding the longest common subsequence between DNA/Protein sequences is one of the basic problems in modern computational molecular biology. But this problem is a little different. Given several DNA sequences, you are asked to make a shortest sequence from them so that each of the given sequence is the subsequence of it.
For example, given "ACGT","ATGC","CGTT" and "CAGT", you can make a sequence in the following way. It is the shortest but may be not the only one.
For example, given "ACGT","ATGC","CGTT" and "CAGT", you can make a sequence in the following way. It is the shortest but may be not the only one.
Input
The first line is the test case number t. Then t test cases follow. In each case, the first line is an integer n ( 1<=n<=8 ) represents number of the DNA sequences. The following k lines contain the k sequences, one per line. Assuming that the length of any sequence is between 1 and 5.
Output
For each test case, print a line containing the length of the shortest sequence that can be made from these sequences.
Sample Input
1
4
ACGT
ATGC
ATGC
CGTT
CAGT
Sample Output
8
Author
LL
参照大神代码优化hash标记节省时间1S以上,碉堡了:
有图有真相:
代码:
1 #include<iostream> 2 #include<stdio.h> 3 #include<string.h> 4 #include<queue> 5 6 #define M 1679616+100000 7 using namespace std; 8 9 struct Nod 10 { 11 int st; 12 int ln; 13 }nd1,nd2; 14 15 int hash[M]; 16 int n,len[8],size,maks; 17 char str[8][8]; 18 char ku[] ="ACGT"; 19 int cas =1; // hash标记用,这里可以节省大量初始化时间(大神专用,哈哈,看的大神代码都这么玩的) 20 21 int bfs() 22 { 23 int pos[8]; 24 queue<Nod> q; 25 nd1.st = 0; 26 nd1.ln = 0; 27 q.push(nd1); 28 // memset(hash,0,sizeof(hash)); //用上面的cas代替初始化过程,节省时间1s以上 29 while(!q.empty()) 30 { 31 nd2 = q.front(); 32 q.pop(); 33 int i,j; 34 int st = nd2.st; 35 for(i=0;i<n;i++) 36 { 37 pos[i] = st%maks; 38 st/=maks; 39 } 40 for(j=0;j<4;j++) 41 { 42 st = 0; 43 for(i=n-1;i>=0;i--) 44 { 45 st = st * maks + pos[i] + (str[i][pos[i]] == ku[j]); 46 } 47 if(hash[st] == cas) continue; 48 if(st == size) return nd2.ln + 1; 49 hash[st] = cas; 50 nd1.ln = nd2.ln + 1; 51 nd1.st = st; 52 q.push(nd1); 53 } 54 } 55 return -1; 56 } 57 58 int main() 59 { 60 int t; 61 scanf("%d",&t); 62 cas = 1; 63 while(t--) 64 { 65 scanf("%d",&n); 66 int i; 67 maks=0; 68 for(i=0;i<n;i++) 69 { 70 scanf("%s",str[i]); 71 len[i] = strlen(str[i]); 72 if(maks<len[i]) maks = len[i]; 73 } 74 maks++; 75 size = 0; 76 for(i=n-1;i>=0;i--) size = size*maks+len[i]; 77 printf("%d\n",bfs()); 78 cas++; //cas加1,用来标记下一组测试数据 79 } 80 return 0; 81 }