HDU 1560 DNA sequence(BFS+hash)

来源:互联网 发布:淘宝网帽子冬季 编辑:程序博客网 时间:2024/06/06 03:50

题目链接:【HDU 1560】

输入n个字符串,找出最短的序列(从前往后,这n个字符串均能在这个序列中找到,不要求连续)

枚举第i个位置的可能性,一共四个字母“ACGT”,我一开始直接记录前i个字符,结果MLE了

用哈希优化,has用来记录枚举到第i个位置时,所有的字符串已经匹配掉后得到的哈希值,v[]用来记录目前已经有多少个字母已经匹配掉了

看题目中的数据,ACGT、ATGC、CGTT、CAGT,假设枚举到第3个位置,得到的字符串是ATC,那么v[1]=2,v[2]=2,v[3]=1,v[4]=1,has就是2211这四个数字的哈希值

有一个时间上的小优化,不要清零,用代码中的cas来取代memset

#include <iostream>#include <algorithm>#include <cstdio>#include <cstring>#include <string>#include <queue>using namespace std;const int inf=1e7;int cas, t, n, maks, size;int vis[inf], len[10];char f[5]="ACGT", str[10][10];int v[10], has;struct node{int has, l;}g, h;int bfs(){queue<node>q;g.has=0, g.l=0;q.push(g);vis[0]=cas;while(!q.empty()){g = q.front(), q.pop();has = g.has;for(int i=0; i<n; i++){v[i] = has%maks;has/=maks;}for(int i=0; i<4; i++){has=0;for(int j=n-1; j>=0; j--){has = has*maks+v[j]+(str[j][v[j]]==f[i]);}if(vis[has]==cas) continue;if(has==size) return g.l+1;vis[has] = cas;h.has=has, h.l=g.l+1;q.push(h);}}return -1;}int main(){scanf("%d", &t);cas=1;while(t--){maks = -1;scanf("%d", &n);for(int i=0; i<n; i++){scanf("%s", str[i]);len[i] = strlen(str[i]);maks=max(maks, len[i]);}maks++, size=0;for(int i=n-1; i>=0; i--) size = size*maks+len[i];printf("%d\n", bfs());cas++;}return 0;}



0 0
原创粉丝点击