CF #582 Div.3 E - two small string (构造字符串,找规律,分析)

给出 n个 a,b,c; 构造一个字符串,其子串不包含题目给出的两个长度为2,只包含a, b ,c的字符串,

假设目标字符串中不能出现 ab  ba   则目标字符串中a和b不能相邻, 所以在目标字符串中所有的a和b只能出现在左右两端。

形如  aaaaccccbbbb

假设目标字符串中不能出现 ac  ca   则目标字符串中a和c不能相邻, 所以在目标字符串中所有的a和c只能出现在左右两端。

形如  aaaabbbbcccc

假设目标字符串中不能出现 bc  cb   则目标字符串中c和b不能相邻, 所以在目标字符串中所有的c和b只能出现在左右两端。

形如  bbbbccccaaaa

......

这是第一种情况, 两个限制字符串直接限制了a,b,c 中的两个字符不能左右相邻,所以要 构造出 n*a n*b n*c 这种形式的字符串.

假设目标字符串中不能出现 ab  bc   因为只有abc三种字符,既然a后面不能跟b,则a后面可以跟c, b后面不能跟c则b后面可以跟a

形如  acbacb

假设目标字符串中不能出现 ac  cb  因为只有abc三种字符,既然a后面不能跟c ,则a后面可以跟b, c后面不能跟b,则c后面可以跟a

形如  abcabc

假设目标字符串中不能出现 ab  ca  因为只有abc三种字符,既然 a后面不能跟b, 则a后面可以跟c, c后面不能跟a,则c后面可以跟b

形如  acbacb

......

这是第二种情况,两个限制字符串只能限制a,b,c 中一个字符不能和另一个字符前后相连,所以要构造出n*(abc)这种形式的字符串.

再测试几个例子,我们发现,所有的例子都属于以上两种情况之一。

因为只有 n*a n*b n*c 和 n*(abc) 这两种形式, 所以可以直接对abc进行全排列,枚举出两种情况中的所有字符串。

而且,通过分析以上两种情况,两个限制串不可能限制abc中两个以上的字符不能左右相邻 或 4个以上字符不能前后相连。所以一定有正确答案。

代码:

#include <stdio.h>
#include <iostream>
#include <vector>
#include <string>
#include <algorithm> 
using namespace std;
int main(){
	int n;
	string a,b;   // 限制串
	cin>>n;       //abc的个数。
	cin>>a>>b;
	string s = "abc";
	vector <string> arr;
	do{
		string x;
		for(int i = 0; i < n; i++){
			x += s; 
		}
		arr.push_back(x);
		arr.push_back(string(n, s[0]) + string(n, s[1]) + string(n, s[2]));
	}while(next_permutation(s.begin(),s.end())); // 排列abc
	
	for(auto str : arr){ 
		if(str.find(a) == string::npos && str.find(b) == string::npos){ 
			cout<<"YES\n"<<str<<endl;
			return 0;
		}
	}
}
发布了52 篇原创文章 · 获赞 114 · 访问量 6010

猜你喜欢

转载自blog.csdn.net/GD_ONE/article/details/101163969