You have two strings and you need to check whether you can cut the second one into three
pieces so that the first string can be concatenated from these three pieces.
----------------------------------------------------------------
Royalitem NO
Romeitaly
----------------------------------------------------------------
Southeastern European Regional Programming Contest
Bucharest, Romania – Vinnytsya, Ukraine
Gym - 101164K
题意:给出字符串A和B,字符串A大小写不区分,字符串B由小写字母构成,构成AB的每种字母的个数相同,询问是否能把B切成3份,重构出字符串A,如果能则输出那三份子串,并按照A的顺序输出。
哈希+枚举
刚开始的时候,以为可以用KMP来过,白白TLE了2发才明白,自己走远了,这题是合适的做法是hash。
O(n^2)的枚举字符串B 的0~i-1 为第一段,i~j-1 为第二段,j~n-1为第三锻,
然后每次借用这三段的哈希值去和A串匹配,这三段有A(3,3) == 6种排列方式,所以枚举这6种排列,
之后借用它们的哈希值判断能否构造出字符串A。
复杂度 O(n^2)
#include
#include
#include
using namespace std;
typedef unsigned long long ull;
const int MAXN = 5e3 + 8;
const ull p = 1e12 + 7; //!
string pa, t;
struct HASH{
ull Hash[MAXN], xp[MAXN];
void init1(int sz){
xp[0] = 1;
for(int i = 1; i <= sz; i++) xp[i] = xp[i-1] * p;
}
void init2(const string &s){//0~n-1 based
int sz = s.size();
Hash[sz] = 0;
for(int i = sz - 1; i >= 0; i--){
Hash[i] = Hash[i+1] * p + (s[i] - 'a' + 1);
}
}
ull get_Hash(const int& st, const int& len){
return Hash[st] - Hash[st + len] * xp[len];
}
} hashp, hasht;
int main()
{
#ifdef LOCAL
freopen("k.txt", "r", stdin);
//freopen("k.out", "w", stdout);
int T = 5;
while(T--){
#endif // LOCAL
ios::sync_with_stdio(false); cin.tie(0);
cin >> pa >> t;
int n = pa.size(), i, j, sz = 0, ans1 = -1, ans1len, ans2 = -1, ans2len, ans3 = -1, ans3len;
for(i = 0; i < n; i++){
if(pa[i] >= 'A' && pa[i] <= 'Z'){
pa[i] = pa[i] - 'A' + 'a';
}
}
hashp.init1(n);
hashp.init2(pa);
hasht.init1(n);
hasht.init2(t);
for(i = 1; i < n - 1; i++){
if(ans1 != -1) break;
for(j = i + 1; j < n; j++){
if(ans1 != -1) break;
//1
if(hasht.get_Hash(0, i) == hashp.get_Hash(0, i)){
if(hasht.get_Hash(i, j - i) == hashp.get_Hash(i, j - i)){
if(hasht.get_Hash(j, n - j) == hashp.get_Hash(j, n - j)){
ans1 = 0, ans1len = i;
ans2 = i, ans2len = j - i;
ans3 = j, ans3len = n - j;
}
}
if(hasht.get_Hash(i, j - i) == hashp.get_Hash(n - (j - i), j - i)){
if(hasht.get_Hash(j, n - j) == hashp.get_Hash(i, n - j)){
ans1 = 0, ans1len = i;
ans2 = j, ans2len = n - j;
ans3 = i, ans3len = j - i;
}
}
}
//2
if(hasht.get_Hash(0, i) == hashp.get_Hash(n - i, i)){
if(hasht.get_Hash(i, j - i) == hashp.get_Hash(0, j - i)){
if(hasht.get_Hash(j, n - j) == hashp.get_Hash(j - i, n - j)){
ans1 = i, ans1len = j - i;
ans2 = j, ans2len = n - j;
ans3 = 0, ans3len = i;
}
}
if(hasht.get_Hash(i, j - i) == hashp.get_Hash(n - j, j - i)){
if(hasht.get_Hash(j, n - j) == hashp.get_Hash(0, n - j)){
ans1 = j, ans1len = n - j;
ans2 = i, ans2len = j - i;
ans3 = 0, ans3len = i;
}
}
}
//3.1
if(hasht.get_Hash(0, i) == hashp.get_Hash(j - i, i)){
if(hasht.get_Hash(i, j - i) == hashp.get_Hash(0, j - i)){
if(hasht.get_Hash(j, n - j) == hashp.get_Hash(j, n - j)){
ans1 = i, ans1len = j - i;
ans2 = 0, ans2len = i;
ans3 = j, ans3len = n - j;
}
}
}
//3.2
if(hasht.get_Hash(0, i) == hashp.get_Hash(n - j, i)){
if(hasht.get_Hash(i, j - i) == hashp.get_Hash(n - (j - i), j - i)){
if(hasht.get_Hash(j, n - j) == hashp.get_Hash(0, n - j)){
ans1 = j, ans1len = n - j;
ans2 = 0, ans2len = i;
ans3 = i, ans3len = j - i;
}
}
}
}
}
if(ans1 == -1) cout << "NO" << endl;
else{
cout << "YES\n" << t.substr(ans1, ans1len) << "\n" << t.substr(ans2, ans2len) << "\n" << t.substr(ans3, ans3len) << endl;
}
#ifdef LOCAL
cout << endl;
}
#endif // LOCAL
return 0;
}
Thank you!
------from ProLights