zoukankan      html  css  js  c++  java
  • Play on Words

    poj1386:http://poj.org/problem?id=1386

    题意:给你n个单词,问你是否能够通过调整单词的顺序存在这样的一个序列,使得 每个单词的首字母是前一个单词的尾字母。
     题解:每个单词可以看做从首字母连向尾字母的一条边,然后就是整个图的欧拉路径。统计每个点的入度和初度,如果基图连通,并且只有两个点入度和初度不等,并且相差分别为1,-1,就存在这样的路径,否则则没。 连通性,可以用并查集. 处理完之后,看每个点的父亲是否相等来判断是否连通。

     1 #include<iostream>
     2 #include<cstring>
     3 #include<algorithm>
     4 #include<cstdio>
     5 using namespace  std;
     6 int in[27], pa[27], out[27];// 统计入度,初读 
     7 bool used[27];//记录出现过的字母 
     8 int n;//单词的个数 
     9 char str[1000];//读取单词 
    10 void UFset(){//初始化 
    11     for(int i=1;i<=26;i++){
    12         used[i]=0;
    13          pa[i]=-1;
    14          out[i]=0;
    15          in[i]=0;
    16     }
    17 }
    18 int Find(int x){//查找 
    19     int s;
    20     for(s=x;pa[s]>=0;s=pa[s]);
    21     while(s!=x){
    22         int temp=pa[x];
    23         pa[x]=s;
    24         x=temp;
    25     }
    26     return s;
    27 }
    28 void Union(int R1,int R2){//合并 
    29     int r1=Find(R1);
    30     int r2=Find(R2);
    31     int temp=pa[r1]+pa[r2];
    32     if(pa[r1]>pa[r2]){
    33         pa[r1]=r2;
    34         pa[r2]=temp;
    35     }
    36     else{
    37         pa[r2]=r1;
    38         pa[r1]=temp;
    39     }
    40 }
    41 bool solve(){//判断连通性 
    42     int first=-1;
    43     for(int i=1;i<=26;i++){
    44         if(!used[i])continue;
    45         if(first==-1)first=Find(i);
    46         else if(first!=Find(i))return false;
    47     }
    48     return true;
    49 }
    50 int main(){
    51   int cas;
    52    scanf("%d",&cas);
    53    while(cas--){
    54        scanf("%d",&n);
    55        UFset();
    56        for(int i=1;i<=n;i++){//建图 
    57            scanf("%s",str);
    58            int len=strlen(str);
    59            int u=str[0]-'a'+1;
    60            int v=str[len-1]-'a'+1;
    61              in[v]++;
    62              used[v]=true;
    63              out[u]++;used[u]=true;
    64              if(Find(u)!=Find(v))
    65                Union(u,v);
    66         }
    67         int one=0,one1=0;bool flag=true;
    68     for(int j=1;j<=26;j++){
    69       if(!used[j])continue;
    70            if(out[j]-in[j]>=2||in[j]-out[j]>=2){
    71                flag=false;
    72                break;
    73            }
    74            if(out[j]-in[j]==1){
    75                one++;
    76                if(one>1)
    77                    {flag=false;break;}
    78            }
    79                if(out[j]-in[j]==-1){
    80                one1++;
    81                if(one1>1){
    82                    flag=false;break;
    83                }
    84               }
    85        }       
    86        if(one!=one1)flag=false;
    87        if(!solve())flag=false;
    88        if(flag)printf("Ordering is possible.
    ");
    89        else
    90        printf("The door cannot be opened.
    ");
    91        }
    92 }
    View Code
  • 相关阅读:
    C# vb实现浮雕特效滤镜效果
    一张图看懂SharpImage
    C#控制操控操作多个UVC摄像头设备
    C#读写修改设置调整UVC摄像头画面-缩放
    继承多态绕点 Java篇
    继承多态绕点 C#篇
    lock关键字理解
    关于C#迭代器
    关于排列组合中组合结果
    C#与Java中相等关系
  • 原文地址:https://www.cnblogs.com/chujian123/p/3383514.html
Copyright © 2011-2022 走看看