使用trie树的特性高效统计同一种颜色出现了多少次,使用并查集将同一块砖的两种颜色连续起来,最终要形成一条直线,意思就是要根据颜色把每块砖都走一遍,也就是欧拉回路或者欧拉路的性质,也就是每个颜色出现的次数必须都是偶数次或者正好有两种颜色次数是奇数次,最后根据并查集的性质可以查看是不是只有一张图,如果出现了一种以上的根节点也不行。
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
int f[510000],d[510000];
char s1[20],s2[20];
struct node
{
int num,sum;
int nex[30];
}t[510000];
int pos=0,num=0;
int findf(int a)
{
return f[a]==a?a:f[a]=findf(f[a]);
}
int creat(char s[])
{
int now=0;
for(int i=0;i<strlen(s);i++)
{
int a=s[i]-'a';
if(t[now].nex[a]==0)
{
t[now].nex[a]=++pos;
now=pos;
}
else
now=t[now].nex[a];
}
if(t[now].num==0)
t[now].num=++num;
d[t[now].num]++;
return t[now].num;
}
int main()
{
memset(d,0,sizeof(d));
for(int i=0;i<=500000;i++)
f[i]=i;
//int o=0;
while(~scanf("%s%s",s1,s2))
{
//o++;
int a=creat(s1);
int b=creat(s2);
if(findf(a)!=findf(b))
{
f[findf(a)]=findf(b);
}
}
int yes=0;
for(int i=1;i<=num;i++)
{
if(d[num]%2==1)
{
yes++;
}
}
if(yes!=0&&yes!=2)
{
printf("Impossible");
return 0;
}
yes=0;
for(int i=1;i<=num;i++)
{
if(f[i]==i)
yes++;
if(yes>1)
{
printf("Impossible");
return 0;
}
}
printf("Possible");
return 0;
}