题意:构造一个最短的字符串,使得给出的n个字符串(只包含ACGT)都是这个字符串的字串(可以不连续),输出字符串的长度。
思路:最短为n个字符串中最长串的长度,最长为n个字符串长度之和,在这个范围内dfs。具体dfs内容见代码注释
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<iostream>
#include<queue>
using namespace std;
typedef long long ll;
char map[10][10];
int len[10];//每个字符串长度
int pos[10];//每个字符串当前匹配到的位置
char s[]="ACGT";
int n;
int flag;
void dfs(int l){
int sum=0;//匹配所需至少还需要的长度
for(int i=0;i<n;i++){
sum=max(sum,len[i]-pos[i]);
}
if(sum==0){
flag=1;
return ;
}
if(sum>l)return ;
int nowpos[10];
for(int i=0;i<n;i++){
nowpos[i]=pos[i];
}
int f=0;
for(int i=0;i<4;i++){
for(int j=0;j<n;j++){
if(map[j][pos[j]]==s[i]){
pos[j]++;
f=1;
}
}
if(f){//当前字母(ACGT中的一个)与n个字符串中的一个匹配
dfs(l-1);//搜索下一层
if(flag)return ;
for(int j=0;j<n;j++){
pos[j]=nowpos[j];
}
}
}
}
int main(){
int t;
scanf("%d",&t);
while(t--){
scanf("%d",&n);
int maxlen=0;
int sum=0;
for(int i=0;i<n;i++){
scanf("%s",map[i]);
len[i]=strlen(map[i]);
maxlen=max(maxlen,len[i]);
sum+=len[i];
}
memset(pos,0,sizeof(pos));
flag=0;
int i;
for(i=maxlen;i<=sum;i++){
dfs(i);
if(flag)break;
}
printf("%d\n",i);
}
return 0;
}