鏈接
http://acm.hdu.edu.cn/showproblem.php?pid=6034
題意
給一組字符串,把每個字母變成
思路
簡單的模擬題(寫寫這題蹭點訪問量2333)
比賽的時候sjt看完這題想到了思路,覺得我比較適合寫這種題(sjt,一個對此博客貢獻巨大的神犇,我只是他的偉大思想的記錄者,逃,2333,= =)
先標記出不能爲0的數,那些在長度大於1的字符串開頭的字母不能爲0。
然後用數組計算每個字母的權值,複雜度cmp()
把每個字母當作指針特殊處理下這個操作。
最後先把可以爲0的數中權值最小的數標記爲0,然後按權值從大到小決定每個字符的取值。
代碼:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define MS(x, y) memset(x, y, sizeof(x));
typedef long long LL;
const int MAXN = 1e5 + 5;
const int MOD = 1e9 + 7;
int n;
int head[MAXN], tail[MAXN];
int val[26];
int weights[26][MAXN], mx_len[26];
int arr[30];
char str[1000005];
bool cmp(int a, int b) {
if (mx_len[a] != mx_len[b]) return mx_len[a] < mx_len[b];
for (int i = mx_len[a]; i >= 0; --i) {
if (weights[a][i] != weights[b][i]) return weights[a][i] < weights[b][i];
}
return false;
}
int main() {
int kase = 0;
while (~scanf("%d", &n)) {
MS(val, -1);
MS(mx_len, 0);
for (int i = 0; i < 26; ++i) weights[i][0] = 0;
for (int i = 1; i <= n; ++i) {
head[i] = tail[i - 1];
scanf("%s", str + head[i]);
tail[i] = head[i] + strlen(str + head[i]);
// 標記出不能爲0的數
if (tail[i] - head[i] > 1) val[str[head[i]] - 'a'] = 1;
for (int j = tail[i] - 1, k = 0; j >= head[i]; --j, ++k) {
if (k > mx_len[str[j] - 'a']) {
mx_len[str[j] - 'a'] = k;
weights[str[j] - 'a'][k] = 0;
}
++weights[str[j] - 'a'][k];
}
}
// cout << str << endl;
for (int i = 0; i < 26; ++i) {
for (int j = 0; j <= mx_len[i]; ++j) {
if (weights[i][j] >= 26) {
if (j + 1 > mx_len[i]) {
mx_len[i] = j + 1;
}
weights[i][j + 1] += weights[i][j] / 26;
weights[i][j] %= 26;
}
}
}
for (int i = 0; i < 26; ++i) arr[i] = i;
sort(arr, arr + 26, cmp);
// 先決定哪個字母爲0
for (int i = 0; i < 26; ++i) if (val[arr[i]] == -1) {
val[arr[i]] = 0;
break;
}
// 接着按權值決定每個字符的取值
int cnt = 25;
for (int i = 25; i >= 0; --i) if (val[arr[i]] != 0) val[arr[i]] = cnt--;
LL ans = 0, tmp;
for (int i = 1; i <= n; ++i) {
tmp = 0;
for (int j = head[i]; j < tail[i]; ++j) {
(tmp *= 26) %= MOD;
(tmp += val[str[j] - 'a']) %= MOD;
}
(ans += tmp) %= MOD;
}
printf("Case #%d: %I64d\n", ++kase, ans);
// 最後一步清空,怕memset太慢了
for (int i = 0; i < 26; ++i) for (int j = 0; j <= mx_len[i]; ++j) weights[i][j] = 0;
}
}