首先我作为一个蒟蒻,拿到字符串题,首先看看能不能无脑哈希
然后于是我们就发现了一个绝妙的做法:暴力枚举每个字符串能够转换成的字符串
于是我们就获得了O(N∗84)的优秀复杂度
显然会T飞QwQ
我们考虑再这个基础上进行优化
我们会发现如果我们O(84)枚举的话,其中有一大部分枚举出来的状态都是重复的
那么我们思考:这其中有多少个状态是有用的呢
首先我们假设我们将sa,sb交换,sc,sd互换($a,b,c,d\in [1, 8] $, a=b=c=d)同时我们令$a < b $ 且 c<d
那么我们会发现最终只有C84∗3种可能是可行的
所以我们只需要把这些预处理出来,那么我们在后面枚举的时候只需要在这些状态中取就行了
最终复杂度O(N∗C84∗3∗8),(最后的8是Hash的复杂度)佐以优秀的常数便可AC此题。
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 
 | 
 #include<bits/stdc++.h>
 
 using namespace std;
 
 #define INF 2147483647
 #define ll long long
 
 int Inp(){
 char c = getchar();
 register int Neg = 1;
 while(c < '0' || c > '9'){
 if(c == '-')
 Neg = -1;
 c = getchar();
 }
 register int Sum = 0;
 while(c >= '0' && c <= '9'){
 Sum = ((Sum << 3) + (Sum << 1)) + c - '0';
 c = getchar();
 }
 return Neg * Sum;
 }
 
 string s[10010];
 bool Used[20];
 
 bool cg[10000000];
 
 inline int Hash(string s){
 int Sum = 0;
 for(int i = 0; i < 8; i++){
 Sum <<= 2;
 switch(s[i]){
 case 'A':{
 Sum += 1;
 break;
 }
 case 'C':{
 Sum += 2;
 break;
 }
 case 'T':{
 Sum += 3;
 break;
 }
 }
 }
 return Sum;
 }
 
 int Hsh[10000];
 int sa[1010];
 int sb[1010];
 int C_swap;
 
 int main(){
 register int n = Inp();
 for(register int i = 1; i <= n; i++)
 cin >> s[i], Hsh[i] = Hash(s[i]);
 for(register int j1 = 0; j1 < 8; j1++){
 Used[j1] = true;
 for(register int j2 = j1 + 1; j2 < 8; j2++){
 if(Used[j2])
 continue;
 Used[j2] = true;
 sa[++C_swap] = j1;
 sb[C_swap] = j2;
 Used[j2] = false;
 }
 Used[j1] = false;
 }
 register int Ans = 0;
 for(register int i = 1; i <= n; i++){
 
 for(int j = 1; j <= C_swap; j++)
 for(int u = j + 1; u <= C_swap; u++){
 if(sa[j] == sa[u] || sb[j] == sb[u] || sa[j] == sb[u] || sb[j] == sa[u])
 continue;
 string s2 = s[i];
 swap(s2[sa[j]], s2[sb[j]]);
 swap(s2[sa[u]], s2[sb[u]]);
 cg[Hash(s2)] = true;
 }
 for(register int j = i + 1; j <= n; j++)
 if(cg[Hsh[j]])
 Ans++, cg[Hsh[j]] = false;
 }
 printf("%d", Ans);
 }
 
 |