POJ 2513 Colored Sticks
题意:有一些木棍,两端有颜色,可以两根木棍接起来,拼起来的一端颜色必须相同,问可不可以拼成一个长木棍。
这个题的基本思路是,首先将字符串映射到 int 离散化。
接下来一个重要的关键是:如果接起来是一根长木棍,中间的接口肯定是两个颜色一样的,这样除了两端,中间的颜色肯定是偶数个。
两端如果颜色也一样,就是各种颜色全部为偶数个。
如果两端颜色不一样,只有这两个颜色是奇数个,其他是偶数个。
然后记录下各种颜色的个数, 如果奇数的颜色不是2或者0那么就不可以。
还要判断下,图片是否连通,比如这组数据:
a b
b a
c d
d c
这样就不可以,虽然颜色都是偶数个
用并查集判断下是否连通就可以了。
接下来还有个问题,每种颜色映射到一个整数,如果是map就超时了,我试过了。
用Tire就不会超时,new或者静态数组都可以。
总结:
1.Tire字典树
2.欧拉回路(并查集判断是否连通,和点的个数统计)
AC代码:
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<set>
#include<map>
#include<vector>
#include<cstdio>
#include<queue>
using namespace std;
const int maxn=250000+10;
char a[15], b[15];
map<string ,int> mp;
int cnt=0;
int gin[maxn*2];
int p[maxn*2];
struct node{
int id;
bool use;
node* next[27];
node(){
id = 0;
use =false;
for(int i = 0; i < 27; ++i)
next[i] = NULL;
}
};
int Find(int u){
return u==p[u]? u: p[u]=Find(p[u]);
}
node *root;\
int hashC(char *str){
node *p = root;
while(*str!=0){
int t = *str -'a';
if(p->next[t]==NULL)
p->next[t] = new node();
p=p->next[t];
++str;
}
if(!p->use){
p->use = true;
p->id = cnt++;
}
return p->id;
}
int main(){
for(int i =0; i<maxn*2;++i) p[i]=i;
root = new node();
while(~scanf("%s%s", a, b)){
int pa = hashC(a);
int pb = hashC(b);
++gin[pa];
++gin[pb];
p[Find(pa)]=Find(pb);
}
bool poss=true;
int dan=0;
for(int i =0;i<cnt;++i){
if(gin[i]&1) ++dan;
}
if(dan!=0&&dan!=2) poss=false;
if(poss){
int dian=0;
for(int i =0; i<cnt;++i){
if(Find(i)==i) ++dian;
if(dian>1){ poss=false; break;}
}
}
if(poss==false) printf("Impossible\n");
else printf("Possible\n");
return 0;
}