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
", 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 }
原文地址:https://www.cnblogs.com/Tree-dream/p/7238059.html