题意:
给定一个字符串,从任意位置把它切为两半,得到两条子串
定义 子串1为s1,子串2为s2,子串1的反串为s3,子串2的反串为s4
给定一个字符串,从任意位置把它切为两半,得到两条子串
定义 子串1为s1,子串2为s2,子串1的反串为s3,子串2的反串为s4
现在从s1 s2 s3 s4中任意取出两个串组合,问有多少种不同的组合方法
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <set>
#include <map>
#include <string>
#include <stack>
#include <queue>
#include <vector>
#define for0(a,b) for(a=0;a<b;++a)
#define for1(a,b) for(a=1;a<=b;++a)
#define foru(i,a,b) for(i=a;i<=b;++i)
#define ford(i,a,b) for(i=a;i>=b;--i)
using namespace std;
typedef double db;
typedef long long ll;
const db eps = 1e-8;
const int inf = 1e9;
const int M = 1e4;
const int maxn = 80;
char s[maxn], p[maxn], q[maxn], rp[maxn], rq[maxn], str[maxn];
char val[M][maxn];
int cnt, n;
//BKDR Hash Function
int hash(char *v){
unsigned int seed = 131;
unsigned int hash = 0;
for(int i=0; v[i]; ++i)
hash = hash * seed + v[i];
return (hash & 0x7FFFFFFF) % M;
}
void contact(char *a, char *b){
int k = 0;
for(int i=0; a[i]; ++i) str[k++] = a[i];
for(int i=0; b[i]; ++i) str[k++] = b[i];
str[k] = '\0';
}
void insert(char *a, char *b){
contact(a, b);
int k = hash(str);
while( (strlen(val[k])>0) && strcmp(str,val[k])!=0){
k = (k+1) % M;
}
if(strlen(val[k])== 0){
strcpy(val[k], str);
cnt++;
}
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.cpp", "r", stdin);
freopen("out.cpp","w", stdout);
#endif // ONLINE_JUDGE
int n, i, j;
scanf("%d", &n);
while(n--)
{
scanf("%s", s);
for0(i,M) val[i][0]='\0';
int len = strlen(s);
int k;
cnt = 0;
for1(i,len-1) {
k = 0;
for0(j,i){
p[j] = s[j];
rp[k++] = s[i-j-1];
}
p[k] = rp[k] = '\0';
k = 0;
foru(j,i,len-1) {
q[j-i] = s[j];
rq[k] = s[len-k-1];
++k;
}
q[k] = rq[k] = '\0';
insert(p, q); insert(q, p);
insert(p, rq); insert(rq, p);
insert(q, rp); insert(rp, q);
insert(rp, rq); insert(rq, rp);
}
printf("%d\n", cnt);
}
return 0;
}