题目大意:给定
1
1
1个母串和
n
n
n个子串,如果
x
x
x是
y
y
y的子序列则
x
x
x可以变换到
y
y
y,求出两个不相交的序列,分别使序列第一个子串可以沿着序列一直变换到母串。(
n
n
n个子串都至少要出现一次,没有合法方案输出
i
m
p
o
s
s
i
b
l
e
impossible
impossible)
这道题也是寒假作业中比较简单的一道题,思路不是非常复杂。
假设有两个序列
A
A
A,
B
B
B,刚开始
A
A
A,
B
B
B中是母串。
那无非三种情况(设目前的字符串为
S
S
S,按长度从大到小先排序):
设
S
S
S如果能变换至
A
A
A的最后一个子串则
g
=
1
g=1
g=1,否则
g
=
0
g=0
g=0。
设
S
S
S如果能变换至
B
B
B的最后一个子串则
h
=
1
h=1
h=1,否则
h
=
0
h=0
h=0。
分类讨论:
1.
g
=
0
a
n
d
h
=
0
1.g=0\ \ and\ \ h=0
1.g=0 and h=0 输出
i
m
p
o
s
s
i
b
l
e
impossible
impossible
2.
g
=
1
a
n
d
h
=
1
2.g=1\ \ and\ \ h=1
2.g=1 and h=1
再多开一个序列
C
C
C,代表能够塞入两个序列的子串。
如果
S
S
S能变换至
C
C
C的最后一个子串,将
S
S
S塞入
C
C
C。
否则?将
S
S
S塞入
A
A
A中,
C
C
C中所有数塞入
B
B
B中(因为
C
C
C中的子串已经违反了它的定义)
3.
g
=
1
3.g=1
3.g=1
将
S
S
S塞入
A
A
A中,
C
C
C中所有数塞入
B
B
B中(
C
C
C中子串也不一定满足定义了,直接扔掉)
4.
h
=
1
4.h=1
4.h=1
同理,将
3
3
3中
A
A
A改成
B
B
B,
B
B
B改成
A
A
A。
然后就可以了。
#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 4005
using namespace std;
char cc[N][N],ch[N];
int len[N];
struct node{
int val,id;
}a[N];
int b[N],c[N],d[N];
int i,j,k,m,n,o,p,l,s,t;
bool cmp(node a,node b) {return a.val>b.val;}
bool Cmp(int x,int y) {return a[x].val<a[y].val;}
int pd(int x,int y)
{
x=a[x].id,y=a[y].id;
if (len[x]>len[y]) return 0;
for (int i=1,j=1;i<=len[y];i++)
{
if (cc[x][j]==cc[y][i]) j++;
if (j>len[x]) return 1;
}
return 0;
}
int main()
{
freopen("match.in","r",stdin);
freopen("match.out","w",stdout);
scanf("%d\n",&n);
for (i=0;i<=n;i++)
{
scanf("%s\n",ch+1),len[i]=strlen(ch+1);
for (j=1;j<=len[i];j++) cc[i][j]=ch[j];
a[i]=(node){len[i],i};
}
sort(a+1,a+n+1,cmp);
b[0]=1,c[0]=1;
for (i=1;i<=n;i++)
{
int g=pd(i,b[b[0]]),h=pd(i,c[c[0]]);
if (g&&h)
{
int f=pd(i,d[d[0]]);
if (f) d[++d[0]]=i;
else {
b[++b[0]]=i;
for (j=1;j<=d[0];j++) c[++c[0]]=d[j];
d[0]=0;
}
} else if (g) {
b[++b[0]]=i;
for (j=1;j<=d[0];j++) c[++c[0]]=d[j];
d[0]=0;
}
else if (h) {
for (j=1;j<=d[0];j++) b[++b[0]]=d[j];
d[0]=0;
c[++c[0]]=i;
}
else {
puts("impossible");return 0;
}
}
for (i=1;i<=d[0];i++) b[++b[0]]=d[i];
sort(b+1,b+b[0]+1,Cmp);
sort(c+1,c+c[0]+1,Cmp);
printf("%d %d\n",b[0]-1,c[0]-1);
for (i=1;i<=b[0]-1;i++)
{
k=a[b[i]].id;
for (j=1;j<=len[k];j++) printf("%c",cc[k][j]);
puts("");
}
for (i=1;i<=c[0]-1;i++)
{
k=a[c[i]].id;
for (j=1;j<=len[k];j++) printf("%c",cc[k][j]);
puts("");
}
return 0;
}