uva 10129 Play on words

思路:把每个单词看做一条边,就变成了在有向图上判断是否存在一个欧拉道路,词头要被词尾连接,所以是入度。注意:

欧拉图的定义:有向图满足欧拉道路的条件就是:1.连通.2.图中入度不等于出度的点最多两个, 一个入度 = 出度 + 1,另一个入度 + 1 = 出度。代码来自: https://blog.csdn.net/u011345461/article/details/9314713

  1 #include<stdio.h>
  2 #include<string.h> 
  3 #define N 1050
  4 int map[N][N], in[N], out[N], vis[N];
  5 int n, m;
  6 
  7 void dfs(int u)
  8 {
  9     vis[u] = 1;
 10     for (int i = 0; i < N; i++)
 11         if (!vis[i] && map[u][i])//在图中且没有被搜过的点
 12             dfs(i);
 13 }//深搜,将点连通
 14 
 15 
 16 int main() {
 17 
 18     scanf("%d", &n);
 19 
 20     while (n--) {
 21 
 22         char str[1050];
 23 
 24         scanf("%d", &m);
 25         memset(map, 0, sizeof(map));
 26         memset(in, 0, sizeof(in));
 27         memset(out, 0, sizeof(out));
 28 
 29         for (int i = 0; i < m; i++) {
 30 
 31             scanf("%s", &str);
 32 
 33             map[str[strlen(str) - 1] - 'a'][str[0] - 'a']++;
 34             out[str[strlen(str) - 1] - 'a']++;//词末字母是出度加一
 35             in[str[0] - 'a']++;//词头是入度    
 36 
 37 
 38         }
 39 
 40         int num1 = 0, num2 = 0;
 41         int flag1 = 1, flag2 = 1;
 42 
 43         //判断奇数点的个数,与是否都是偶数点
 44         for (int i = 0; i < N; i++)
 45         {
 46             if (flag1 == 0)
 47                 break;
 48             if (out[i] != in[i])
 49                 if (in[i] == out[i] + 1)//出入度不一样,数奇数点的个数
 50                 {
 51                     num1++;
 52                 }
 53                 else if (out[i] == in[i] + 1)
 54                 {
 55                     num2++;
 56                 }
 57                 else//不符合奇数点的条件
 58                 {
 59                     flag1 = 0;
 60                     break;
 61                 }
 62         }
 63 
 64         if (num1 && num2 && num1 + num2 > 2) //奇数点个数大于2
 65             flag1 = 0;
 66 
 67         if (flag1) {
 68 
 69             memset(vis, 0, sizeof(vis));
 70             for (int i = 0; i < N; i++)
 71                 if (in[i])
 72                 {
 73                     dfs(i);
 74                     break;
 75                 }
 76 
 77             //判断是否有度数的点都有遍历到        
 78             for (int i = 0; i < N; i++)
 79             {
 80                 if (in[i] && !vis[i])
 81                 {
 82                     flag2 = 0;
 83                     break;
 84                 }
 85                 if (out[i] && !vis[i])
 86                 {
 87                     flag2 = 0;
 88                     break;
 89                 }
 90             }
 91 
 92             if (flag2)
 93                 printf("Ordering is possible.\n");
 94             else
 95                 printf("The door cannot be opened.\n");
 96         }
 97         else
 98             printf("The door cannot be opened.\n");
 99 
100     }
101 
102     return 0;
103 }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值