UVa10129 - Play on Words

c++11CE了c++AC了

 欧拉道路 + 并查集

#include<cstring>
#include<iostream>
#include<cstdio>
#include<cmath>
#define MAXN 30
using namespace std;
int vis[MAXN], N, T, f[MAXN],rank[MAXN], in[MAXN], out[MAXN];

void init()
{
    for(int i = 0; i < MAXN; i++)
        f[i] = i,rank[i] = 0;
}

int find(int x)
{
    int r = x;
    while(f[r]!=r)
        r = f[r];
    f[x] = r;
    return r;
}

void Union(int x, int y)
{
    x = find(x);
    y = find(y);
    if(rank[x] > rank[y]){
        f[y] = x;
    }else{
        if(rank[x] == rank[y]){
            rank[y]++;
        }
        f[x] = y;
    }
}
int main()
{
    scanf("%d", &T);
    while(T--){
        memset(in, 0, sizeof(in));
        memset(out, 0, sizeof(out));

        char str[1005];
        init();
        scanf("%d", &N);
        for(int i = 0; i < N; ++i){
            scanf("%s", str);
            ++out[str[0] - 'a'];
            ++in[str[strlen(str) - 1] - 'a'];
            Union(str[0] - 'a', str[strlen(str) - 1] - 'a');
        }

        int cnt = 0;
        for(int i= 0; i <27; ++i){
            if((in[i] || out[i]) && f[i] == i)
                ++cnt;
        }

        bool flag = true;
        if(cnt != 1) flag = false;

        int num1=0, num2=0;
        for(int i = 0; i <MAXN ; i++){
            if(!flag) break;
            if(in[i]!=out[i]){
                if(in[i] == out[i]+1) { ++num1; }
                else if(out[i] == in[i] + 1) {++num2;}
                else { flag = false; break; }
            }
        }
        if(num1 && num2 && num1 + num2 > 2) flag = false;
        if(flag){
            printf("Ordering is possible.\n");
        }else{
            printf("The door cannot be opened.\n");
        }
    }
    return 0;
}

. 欧拉道路 + dfs

#include<cstring>
#include<iostream>
#include<cstdio>
#include<cmath>
#define MAXN 100
using namespace std;
int vis[MAXN],G[MAXN][MAXN],N,T,f[MAXN],rank[MAXN],in[MAXN],out[MAXN];
void dfs(int u){
    vis[u] = true;
    for(int i = 0; i <MAXN; ++i){
        if(G[u][i] && !vis[i])
            dfs(i);
    }
}
int main()
{
    scanf("%d", &T);
    while(T--){
        memset(G, 0, sizeof(G));
        memset(in, 0, sizeof(in));
        memset(out, 0, sizeof(out));

        char str[1005];
        scanf("%d", &N);

        for(int i=0; i<N; ++i){
            scanf("%s", str);
            ++G[str[0] - 'a'][str[strlen(str) - 1] - 'a'];
            ++out[str[0] - 'a'];
            ++in[str[strlen(str)- 1] - 'a'];
        }

        bool flag = true;
        int num1 = 0, num2 = 0;
        for(int i =  0; i < MAXN; ++i) {
            if(!flag) break;
            if(in[i] != out[i]) {
                if(in[i] == out[i] + 1) { ++num1; }
                else if(out[i] == in[i] + 1) { ++num2; }
                else { flag = false; break; }
            }
        }
        if(num1 && num2 && num1+num2 > 2) flag = false;

        if(flag){
            memset(vis, 0, sizeof(vis));
            for(int i = 0; i < MAXN; ++i)
            if(out[i]) {dfs(i); break;}

            bool flag2 = true;
            for(int i = 0; i < MAXN; ++i) {
                if(in[i] && !vis[i]) { flag2 = false; break; }
                if(out[i] && !vis[i]) { flag2 = false; break; }
            }
            if(flag2) printf("Ordering is possible.\n");
            else  printf("The door cannot be opened.\n");
        }
        else {
            printf("The door cannot be opened.\n");
        }
    }
    return 0;
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值