码迷,mamicode.com
首页 > 其他好文 > 详细

hdu - 6282,2018CCPC湖南全国邀请赛G题,字符串,规律

时间:2018-06-02 21:29:27      阅读:238      评论:0      收藏:0      [点我收藏+]

标签:相互转换   第一个   ring   accept   操作   情况   问题   char   子串   

HDU – 6282

http://acm.hdu.edu.cn/showproblem.php?pid=6282

by Hzu_Tested

 

题意:给出两个字符串S和T,只由a,b,c三种字符组成(不为空串,长度不一定相同,不一定包含所有字符)。对字符串S可以进行几种操作:在任意位置添加/删除字符串aa,bb,abab。问字符串S是否能通过以上几种操作变成T,输出Yes/No。

 

思路:字符串变化的问题,先找出所有可行的操作:添加/删除aa,bb,abab,即只能添加/删除偶数个a/b,无法添加/删除c,那么如果S和T的字符c的个数不等则一定是No。

再看到第一个样例ab->ba,则ba->ab也可行(添加和删除互为逆操作),发现隐藏操作ab<-->ba。

技术分享图片

那么ab的位置关系就无所谓了,因为可以随意交换ab的位置(没有c的情况下),则只剩ab的个数关系需要比较,又因为可以任意添加/删除偶数个a/b,则ab的个数关系只需要比较奇偶性即可。

那么,对于没有字符c的串str1和str2,只要str1中a的个数的奇偶和str2中a的个数的奇偶相同,且str1中b的个数的奇偶和str2中b的奇偶相同,则str1和str2就能相互转换。

对于有字符c的情况,只需以每个c作为分割,比较每一个子串即可。

 技术分享图片

所有对应子串都能相互转换,则S和T能相互装换。

 

(比较暴力的写法,不是很好看...)

技术分享图片
 1 #include <cstdio>
 2 #include <cstring>
 3 using namespace std;
 4 
 5 const int maxn = 10000+10;
 6 char str[maxn];
 7 int strc[maxn];
 8 int cnt1;
 9 char goal[maxn];
10 int goalc[maxn];
11 int cnt2;
12 
13 int main() {
14     while(scanf("%s",str)!=EOF) {
15         scanf("%s",goal);
16         int len = strlen(str);
17         cnt1 = 0;
18         strc[cnt1++] = -1;
19         for(int i=0;i<len;++i) {
20             if(str[i]==c) {
21                 strc[cnt1++] = i;
22             }
23         }
24         int len2 = strlen(goal);
25         cnt2 = 0;
26         goalc[cnt2++] = -1;
27         for(int i=0;i<len2;++i) {
28             if(goal[i]==c) {
29                 goalc[cnt2++] = i;
30             }
31         }
32         bool ok = false;
33         if(cnt1==cnt2) {
34             ok = true;
35             int a1,b1,a2,b2;
36             for(int i=1;i<cnt1;++i) {
37                 a1 = 0, b1 = 0, a2 = 0, b2 = 0;
38                 for(int j=strc[i-1]+1;j<strc[i];++j) {
39                     if(str[j]==a){
40                         ++a1;
41                     } else if(str[j]==b) {
42                         ++b1;
43                     }
44                 }
45                 for(int j=goalc[i-1]+1;j<goalc[i];++j) {
46                     if(goal[j]==a) {
47                         ++a2;
48                     } else if(goal[j]==b) {
49                         ++b2;
50                     }
51                 }
52                 if(a1%2!=a2%2 || b1%2!=b2%2) {
53                     ok = false;
54                     break;
55                 }
56             }
57             if(ok) {
58                 a1 = 0, b1 = 0, a2 = 0, b2 = 0;
59                 for(int i=strc[cnt1-1]+1;i<len;++i) {
60                     if(str[i]==a) {
61                         ++a1;
62                     } else if(str[i]==b) {
63                         ++b1;
64                     }
65                 }
66                 for(int i=goalc[cnt2-1]+1;i<len2;++i) {
67                     if(goal[i]==a) {
68                         ++a2;
69                     } else if(goal[i]==b) {
70                         ++b2;
71                     }
72                 }
73                 if(a1%2!=a2%2 || b1%2!=b2%2) {
74                     ok = false;
75                 }
76             }
77         }
78         printf("%s\n",ok?"Yes":"No");
79     }
80     return 0;
81 }
Accept Code

 要注意,如果有cnt个c,那么需要比较的子串一共有cnt+1,不要少比较了。

 

hdu - 6282,2018CCPC湖南全国邀请赛G题,字符串,规律

标签:相互转换   第一个   ring   accept   操作   情况   问题   char   子串   

原文地址:https://www.cnblogs.com/hzuCode/p/9126821.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!