POJ 3087 Shuffle'm Up

  赤裸裸的模拟题。。

  给出字符串 s1,s2,s12;判断s1,s2能够通过题目中所给的规则到达 s12。每次只会产生一种新的状态,还BFS个毛线--

  s1的首位新生成的字符串的首,s2的尾为新生成字符串的尾。中间的字符依次交叉排列。

  再将新生成的字符串的前一半给s1,后一半给s2。

  重复上述两步 直到到达 s12 或者 新生成的字符串已经出现过。

  前者输出步数,后者输出 -1。

  

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <cstdio>
 4 #include <cstring>
 5 #include <cmath>
 6 
 7 using namespace std;
 8 
 9 struct N
10 {
11     char s[210];
12     N *l,*r;
13 };
14 
15 N *creat()
16 {
17     N *p = (N *)malloc(sizeof(N));
18     p->l = p->r = NULL;
19     return p;
20 }
21 
22 bool check(char *s,N *&root)
23 {
24     if(root == NULL)
25     {
26 
27         root = creat();
28         strcpy(root->s,s);
29 
30         return true;
31     }
32     int order = strcmp(s,root->s);
33 
34     if(order == 0)
35         return false;
36 
37     if(order < 0)
38         return check(s,root->l);
39 
40     return check(s,root->r);
41 }
42 
43 int main()
44 {
45     int T,icase = 0,ans;
46 
47     scanf("%d",&T);
48 
49     while(T--)
50     {
51         int len,i;
52 
53         char s1[110],s2[110],s12[210],t[210];
54 
55         N *root = NULL;
56         ans = 0;
57 
58         scanf("%d%*c",&len);
59 
60         scanf("%s%s%s",s1,s2,s12);
61 
62         strcpy(t,s12);
63 
64         while(check(t,root))
65         {
66             ++ans;
67             for(i = 0;i < len; ++i)
68             {
69                 t[2*i] = s2[i];
70                 t[2*i+1] = s1[i];
71             }
72             t[2*len] = '\0';
73             for(i = 0;i < len; ++i)
74             {
75                 s2[i] = t[i+len];
76                 s1[i] = t[i];
77             }
78             s1[len] = s2[len] = '\0';
79         }
80         if(strcmp(t,s12) == 0)
81             printf("%d %d\n",++icase,ans);
82         else
83             printf("%d -1\n",++icase);
84     }
85     return 0;
86 }
View Code

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值