HDU 6034 Balala Power! 排序 贪心
2017-07-25 21:52
429 查看
链接
http://acm.hdu.edu.cn/showproblem.php?pid=6034题意
给一组字符串,把每个字母变成[0,25]中的一个数(不准有两个字母变成的数相同),求这一组26进制数转换成10进制后的最大和(不准出现前缀0),模1e7思路
简单的模拟题(写写这题蹭点访问量2333)比赛的时候sjt看完这题想到了思路,觉得我比较适合写这种题(sjt,一个对此博客贡献巨大的神犇,我只是他的伟大思想的记录者,逃,2333,= =)
先标记出不能为0的数,那些在长度大于1的字符串开头的字母不能为0。
然后用数组计算每个字母的权值,复杂度O(26∗1e5),每个字母在某个位置,其对应的26进制数的某位就要多个1,用数组模拟这个数,然后从底位到高位把大于等于26的值进位,然后对这些数排序,显然直接排序划不来,我们用一个
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; } }
相关文章推荐
- 2017 Multi-University Training Contest - Team 1 1002&&HDU 6034 Balala Power!【字符串,贪心+排序】
- hdu 6034 Balala Power!(贪心)( 2017 Multi-University Training Contest - Team 1 )(无耻之sort)
- hdu 6034 Balala Power!(贪心)( 2017 Multi-University Training Contest - Team 1 )(无耻之sort)
- HDU 6034 Balala Power!(贪心)
- HDU 6034 Balala Power!(贪心)
- hdu 6034 Balala Power!(贪心)( 2017 Multi-University Training Contest - Team 1 )(无耻之sort)
- hdu 6034 Balala Power!(贪心)( 2017 Multi-University Training Contest - Team 1 )(无耻之sort)
- 【HDU 6034】Balala Power!(贪心+进制转换)
- HDU 6034 Balala Power! (位权排序)
- HDU-6034 Balala Power! - 2017 Multi-University Training Contest - Team 1(贪心)
- hdu 6034 Balala Power!(贪心)( 2017 Multi-University Training Contest - Team 1 )(无耻之sort)
- HDU 6034 Balala Power! (贪心)
- HDU 6034 17多校1 Balala Power!(思维 排序)
- hdu 6034 Balala Power!(贪心)( 2017 Multi-University Training Contest - Team 1 )(无耻之sort)
- HDU 2017 多校联合训练赛1 1002 6034 Balala Power 排序
- hdu 6034 Balala Power!(贪心)
- hdu 6034 Balala Power!(贪心)( 2017 Multi-University Training Contest - Team 1 )(无耻之sort)
- HDU 6034 Balala Power!(贪心)
- hdu 6034 Balala Power!(贪心)( 2017 Multi-University Training Contest - Team 1 )(无耻之sort)
- 2017多校第一场 HDU 6034 Balala Power! 贪心,细节题