题意:
给定一个字符串,从任意位置把它切为两半,得到两条子串
定义 子串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; }
时间: 2024-10-15 18:35:15