关键在排序!!!
数组间的排序会超时,所以需要把一个数组映射成一个数字,就可以了
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int maxn = 1e5 + 5; const ll Mod = 1e9 + 7; int len,ltt[26][maxn]; char s[maxn]; bool apr[26]; ll pow26[maxn]; void init() { int len = strlen(s); for(int i = 0; i < len; i++) ltt[s[i]-'a'][len - 1 - i]++; } bool cmp(int A, int B) { for (int i = len - 1 ; i >= 0 ; -- i) { if (ltt[A][i] != ltt[B][i]) return ltt[A][i] < ltt[B][i]; } return 0; } int main() { // freopen("in.txt","r",stdin); int n; int kase = 1; pow26[0] = 1; for(int i = 1; i < maxn; i++) pow26[i] = pow26[i-1]*26%Mod; while(~scanf("%d", &n)) { memset(apr, 0, sizeof(apr)); memset(ltt, 0, sizeof(ltt)); len = 0; for(int i = 0; i < n; i++) { scanf("%s",s); int len1 = strlen(s); if(len1 > 1) apr[s[0] - 'a'] = 1; len = max(len,len1); init(); } int a[26]; //a数组是ltt数组的映射 //进位 for(int i = 0; i < 26; i++) { for(int j = 0; j < len; j++) { ltt[i][j+1] += ltt[i][j]/26; ltt[i][j] %= 26; } while(ltt[i][len]) { ltt[i][len+1] += ltt[i][len]/26; ltt[i][len++] %= 26; } a[i] = i; } sort(a, a + 26, cmp); int num[26] = {0}; if(len > 1) { bool flag = 1; int v = 1; for(int i = 0; i < 26; i++) { if(flag && !apr[a[i]]) { num[i] = 0; flag = 0; } else num[i] = v++; } } else { for(int i = 0; i < 26; i++) num[i] = i; } ll res = 0; for(int i = 0; i < 26; i++) for(int j = 0; j < len; j++) res = (res + num[i]*ltt[a[i]][j]*pow26[j])%Mod; printf("Case #%d: %I64d ", kase++, res); } return 0; }