题意:给出一个字符串s,可以任意分割成两个字符串s1和是s3,s1和s3可以得出顺序相反的反串s2和s4.由四个串可以两两组合,求一共能组合多少个不同的字符串。
思路:hash表或者字典树均可。字典树简单一点,而且叶子都在同一层,处理起来方便一些。
#include<iostream>
#include<cstring>
using namespace std;
char a[80];
int size;
struct node
{
int val;
node* ptr[26];
}mem[100000];
node* new_node(){
return mem+(size++);
}
node* root;
int sum;
void build_str(char* str){
node* p = root;
while(*str){
int t = *str - 'a';
if (p->ptr[t] == NULL){
node* q = new_node();
q->val = 0;
memset(q->ptr, 0, sizeof(q->ptr));
p->ptr[t] = q;
p = q;
}
else{
p = p->ptr[t];
}
str++;
}
p->val = 1;
}
int check(char* str){
node* p = root;
char* s = str;
while(*str){
int t = *str - 'a';
if (p->ptr[t] == NULL){
build_str(s);
return 1;
}else{
p = p->ptr[t];
str++;
}
}
return 0;
}
void match_up(int len, int in){
char b[500];
//F is order, L is inor
for (int i = 0; i < len; i++){
if (i <= in) b[i] = a[i];
else b[i] = a[len-(i-in)];
}
b[len]='\0';
//cout << b << endl;
sum += check(b);
//F is inor, L is order
for (int i = 0; i < len; i++){
if (i <= in) b[i] = a[in - i];
else b[i] = a[i];
}
b[len] = '\0';
sum += check(b);
//cout << b << endl;
//F is inor, L is inor
for (int i = 0; i < len; i++){
if (i <= in) b[i] = a[in-i];
else b[i] = a[len-i+in];
}
b[len] = '\0';
sum += check(b);
//cout << b << endl;
//L is order, F is order
for (int i = 0; i < len; i++){
if (len - i -1 > in) b[i] = a[in+i+1];
else b[i] = a[in-len+i+1];
}
b[len] = '\0';
sum += check(b);
//cout << b << endl;
//L is order, F is inor
for (int i = 0; i < len; i++){
if (len - i -1 > in) b[i] = a[in+i+1];
else b[i] = a[len-i-1];
}
b[len] = '\0';
sum += check(b);
//cout << b << endl;
//L is inor, F is order
for(int i = 0; i < len; i++){
if (len-i-1 > in) b[i] = a[len-i-1];
else b[i] = a[in-len+i+1];
}
b[len] = '\0';
sum += check(b);
//cout << b << endl;
//L is inor, F is inor
for (int i = 0; i < len; i++){
if (len-i-1 > in) b[i] = a[len-i-1];
else b[i] = a[len-i-1];
}
b[len] = '\0';
//cout << b << endl;
sum += check(b);
}
int main(){
int test;
scanf("%d", &test);
while(test--){
size = 0;
sum = 0;
root = new_node();
for (int i = 0; i < 26; i++){
root->ptr[i] = NULL;
}
scanf("%s", a);
build_str(a);
int len = strlen(a);
for (int i = 0; i < len; i++)
match_up(len, i);
printf("%d\n", sum+1);
}
}