2018湖南湘潭CCPC邀请赛 && HDU6282: G. String Transformation(思维题)

 

String Transformation

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 553    Accepted Submission(s): 175

Problem Description

Bobo has a string S=s1s2…sn consists of letter `a`, `b` and `c`.
He can transform the string by inserting or deleting substrings `aa`, `bb` and `abab`.
Formally, A=u∘w∘v (``∘'' denotes string concatenation) can be transformed into A′=u∘v and vice versa where u, v are (possibly empty) strings and w∈{aa,bb,abab}.
Given the target string T=t1t2…tm, determine if Bobo can transform the string S into T.

Input

The input consists of several test cases and is terminated by end-of-file.
The first line of each test case contains a string s1s2…sn.
The second line contains a string t1t2…tm.

Output

For each test case, print `Yes` if Bobo can. Print `No` otherwise.
## Constraint
* 1≤n,m≤104
* s1,s2,…,sn,t1,t2,…,tm∈{a,b,c}
* The sum of n and m does not exceed 250,000.

Sample Input

ab ba ac ca a ab

Sample Output

Yes No No

 

题意:

给你两个只包含字母"abc"的字符串S,T,问能不能通过下述条件将第一个串转成第二个串:①可以从中删除子串"aa","bb","abab",②可以从中任意一个位置添加子串"aa","bb","abab"

 

思路:

第一个样例已经完美说明这道题该怎么做了

这两个转换有三个性质:

  1. 第二个转换明显是第一个转换的逆转换,因此如果S能变成T,那么T也一定能变成S
  2. 无论怎么转换,字符a个数的奇偶性一定不会被改变,同理b也是
  3. ab和ba能相互转换,aa和bb显然也可以,这就说明和两个串a和b位置无关

这样子只要看下c的数量是否相等(因为c不能动的),如果相等的话再看S和T相邻两个c中a和b出现的数量是否奇偶性相同即可

 

#include<stdio.h>
#include<string.h>
char s1[10005], s2[10005];
int c1[10005], c2[10005], a1[10005], a2[10005], b1[10005], b2[10005];
int main(void)
{
	int n, m, chk, i;
	while(scanf("%s%s", s1+1, s2+1)!=EOF)
	{
		chk = 0;
		n = strlen(s1+1);
		m = strlen(s2+1);
		for(i=1;i<=n;i++)
			chk += (s1[i]=='c');
		for(i=1;i<=m;i++)
			chk -= (s2[i]=='c');
		if(chk)
			printf("No\n");
		else
		{
			for(i=1;i<=n+1;i++)
			{
				a1[i] = a1[i-1]+(s1[i]=='a');
				b1[i] = b1[i-1]+(s1[i]=='b');
				if(s1[i]=='c')
					c1[++chk] = i;
			}
			c1[++chk] = n+1;
			chk = 0;
			for(i=1;i<=m+1;i++)
			{
				a2[i] = a2[i-1]+(s2[i]=='a');
				b2[i] = b2[i-1]+(s2[i]=='b');
				if(s2[i]=='c')
					c2[++chk] = i;
			}
			c2[++chk] = m+1;
			for(i=1;i<=chk;i++)
			{
				if((a1[c1[i]]-a1[c1[i-1]])%2!=(a2[c2[i]]-a2[c2[i-1]])%2 || (b1[c1[i]]-b1[c1[i-1]])%2!=(b2[c2[i]]-b2[c2[i-1]])%2)
				{
					printf("No\n");
					break;
				}
			}
			if(i==chk+1)
				printf("Yes\n");
		}
	}
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值