hdu 6034

http://acm.hdu.edu.cn/showproblem.php?pid=6034

首次参加多校训练,不得不说还是太菜了,弱爆了

这个题目在比赛的时候一直在想这个问题,怎么来记录它的权值,然后再用权值排序,想了很久都没能解决这个问题,最后结束了,看了一下题解

发现还是太菜了

题目:给你一些字符串,每个字符用0-25进行替换,要求转换成26进制后,总和最大

思路:首先转换成26进制也就是在位置上乘以26i然后加起来,由此可知字符串前面的字母用大的数字进行替换的话,那么总和加起来就会大,但是如果后面一个字母

总共的次数加起来超过了26次的话,那么这个它的权值比前面那个字母就要大了,主要注意这里,然后用一个26*100000的数组来记录,每个字母的权值,然后根据这个对此进行排序

  1 #include <stdio.h>
  2 #include <string.h>
  3 #include <iostream>
  4 #include <string>
  5 #include <algorithm>
  6 #define maxn 100005
  7 #define mod 1000000007
  8 using namespace std;
  9
 10 char str[maxn];
 11 int power[maxn];
 12 int num[26][maxn];
 13 int sum[26];
 14 int a[26];
 15 int n,maxl;
 16 int cnt = 1;
 17 bool vis[26];
 18
 19 bool cmp(int a, int b)
 20 {
 21     for (int i = maxl-1; i >= 0; i--)
 22         if (num[a][i] != num[b][i])
 23             return num[a][i] < num[b][i];
 24     return false;
 25 }
 26
 27 void calc()
 28 {
 29     memset(num, 0, sizeof(num));
 30     memset(vis, false, sizeof(vis));
 31     memset(sum, 0, sizeof(sum));
 32     maxl = 0;
 33     for (int i = 0; i < n; i++)
 34     {
 35         scanf("%s", str);
 36         vis[str[0] - ‘a‘] = true;
 37         int len = strlen(str);
 38         int cnt = 0,tmp;
 39         for (int j = len-1; j >=0 ; j--)
 40         {
 41             tmp = str[j] - ‘a‘;
 42             num[tmp][cnt]++;
 43             sum[tmp] += power[cnt++];
 44             if (sum[tmp] >= mod)
 45                 sum[tmp] -= mod;
 46         }
 47         if (maxl < len)
 48             maxl = len;
 49     }
 50 }
 51
 52 void solve()
 53 {
 54     for (int i = 0; i < 26; i++)
 55     {
 56         for (int j = 0; j < maxl ; j++)
 57         {
 58             num[i][j + 1] += num[i][j] / 26;
 59             num[i][j] %= 26;
 60         }
 61         while (num[i][maxl])
 62         {
 63             num[i][maxl + 1] += num[i][maxl] / 26;
 64             num[i][maxl++] %= 26;
 65         }
 66         a[i] = i;
 67     }
 68     sort(a, a + 26, cmp);
 69     int first = -1;
 70         //除去前导0.
 71     for (int i = 0; i < 26; i++)
 72     {
 73         if (!vis[a[i]])
 74         {
 75             first = a[i];
 76             break;
 77         }
 78     }
 79     int ans = 0, x = 25;
 80     for (int i = 25; i >=0; i--)
 81     {
 82         if(a[i]!=first)
 83         {
 84             ans += (long long)(x--)*sum[a[i]] % mod;
 85             ans %= mod;
 86         }
 87
 88     }
 89     printf("Case #%d: %d\n", cnt++, ans);
 90 }
 91
 92
 93 int main()
 94 {
 95     power[0] = 1;
 96        //权值
 97     for (int i = 1; i < maxn; i++)
 98     {
 99         power[i] = (long long)power[i - 1] * 26 % mod;
100     }
101     //freopen("in.txt","r",stdin);
102     while (~scanf("%d", &n))
103     {
104         calc();
105         solve();
106     }
107     return 0;
108 }
时间: 2024-08-04 13:23:59

hdu 6034的相关文章

HDU 6034 Balala Power!(贪心+排序)

Balala Power! Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total Submission(s): 1411    Accepted Submission(s): 239 Problem Description Talented Mr.Tang has n strings consisting of only lower case characters.

hdu 6034 Balala Power!

题目链接:hdu 6034 Balala Power! 题意: 给你n个字符串,都是包含小写字母,现在让你给a~z赋值0~25,使得这些字符串变成的26进制的数的总和最大. 不能有前导0的情况,他们保证至少有一个字母不出现在第一位. 题解: 每个字符对答案的贡献都可以看作一个 26 进制的数字,问题相当于要给这些贡献加一个 0 到 25 的权重使得答案最大.最大的数匹配 25,次大的数匹配 24,依次类推.排序后这样依次贪心即可,唯一注意的是不能出现前导 0. 前导0的具体处理看代码. 1 #i

Balala Power! HDU - 6034

Balala Power! HDU - 6034 题意:给n个字符串,让你给每一个小写字母赋一个值(0到25),使得所有的字符串的总和最大. 把每一个字符串看作一个26进制的数 先统计每个字母在不同位置出现的次数,然后按出现次数的多少排序,出现的多的自然赋大的值 注意题目要求不能有前导零,所以排序后拍到最后的那个字母如果在某个字符串首位出现过,就要和前面的换一下 1 #include <bits/stdc++.h> 2 using namespace std; 3 #define ll lon

2017 Multi-University Training Contest - Team 1 1002&amp;&amp;HDU 6034 Balala Power!【字符串,贪心+排序】

Balala Power! Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 2668    Accepted Submission(s): 562 Problem Description Sample Input 1 a 2 aa bb 3 a ba abc Sample Output Case #1: 25 Case #2: 132

HDU 6034 【贪心】

传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6034 题意: 给出 N 个字符串,要求我们对每个字符映射成 0~25中的一个数字,要求最后所有字符串转换为26进制能得到的最大值. 解题思路: 统计每个字符在每一位上得贡献(用数组模拟26进制),然后按照这个模拟得26进制诸位比较, 贪心映射: 但是注意一个点就是不能出现前缀 0  的情况,所以我们要标记哪种字符可以作为前缀0哪种不可以,排序完后处理一下不满足前缀 0 的情况,最后暴力答案即可: AC

HDU 6034 6038

6034:给每个字母26进制的贪心.例如一个字母 c = 7*26^89 + 6*26^50.... 这个字符串有10^5长度.普通的大整数会超时,这里要稀疏这个大数一个pair<int,int> 型即可 (89,7),计算好每一个字母的贡献值,排序. 前导0的处理是,如果要用到0了,说明所有字母都出现了,那么从后往前,如果一个数他贡献值最小而且可以为0,那他就是0: 6038:

HDU 6034 Balala Power! (贪心+坑题)

题意:给定一个 n 个字符串,然后问你怎么给 a-z赋值0-25,使得给定的字符串看成26进制得到的和最大,并且不能出现前导0. 析:一个很恶心的题目,细节有点多,首先是思路,给定个字符一个权值,然后要注意的进位,然后排序,从大到小,给每个字符赋值,如果最后一个出现前导0,就得向前找一个最小的不在首字符的来交换,但不能动了相对的顺序. 代码如下: #pragma comment(linker, "/STACK:1024000000,1024000000") #include <c

HDU 6034 Balala Power!【排序/进制思维】

Balala Power![排序/进制思维] Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 6703    Accepted Submission(s): 1680 Problem Description Talented Mr.Tang has n strings consisting of only lower case cha

HDU 6203 ping ping ping [LCA,贪心,DFS序,BIT(树状数组)]

题目链接:[http://acm.hdu.edu.cn/showproblem.php?pid=6203] 题意 :给出一棵树,如果(a,b)路径上有坏点,那么(a,b)之间不联通,给出一些不联通的点对,然后判断最少有多少个坏点. 题解 :求每个点对的LCA,然后根据LCA的深度排序.从LCA最深的点对开始,如果a或者b点已经有点被标记了,那么continue,否者标记(a,b)LCA的子树每个顶点加1. #include<Bits/stdc++.h> using namespace std;