2017北航多校B 思维+大数
Posted hesorchen
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2017北航多校B 思维+大数相关的知识,希望对你有一定的参考价值。
题目
给出至多1e5个小写字母串,现在请你对每个字母一对一赋值[0,25],这样每个字符串可以看作是一个二十六进制字符串,将每个二十六进制字符串转化成十进制后,加起来的和最大是多少。对结果取模1e9+7。
解题思路
比赛时考虑从高位往低位判断,也就是从25开始赋值。一个坑点是不能有前导0,从大到小赋值会出现问题。
应该先确定将0赋值给哪个字母,再考虑其他字母。
AC代码
#include <bits/stdc++.h>
using namespace std;
const int N = 100105, M = 30, mod = 1e9 + 7;
int n;
int num[N][M];
string s[N];
set<int> vis;
struct node
{
int x;
string s2;
bool operator<(const node temp) const
{
return s2 < temp.s2;
}
} tt[M];
map<int, int> val;
long long f(string s)
{
long long a = 1, ans = 0;
for (auto it = s.rbegin(); it != s.rend(); it++)
{
ans += (val[*it - 'a' + 1] * a) % mod;
ans %= mod;
a = a * 26 % mod;
}
return ans;
}
long long get()
{
long long res = 0;
for (long long i = 1; i <= n; i++)
{
res = res + f(s[i]);
res %= mod;
}
return res;
}
int CA;
void init()
{
memset(num, 0, sizeof num);
val.clear();
vis.clear();
for (int i = 1; i <= 26; i++)
tt[i].s2.clear();
}
void solve()
{
init();
int mx = 0;
for (int i = 1; i <= n; i++)
{
cin >> s[i];
if (s[i].size() >= 2)
{
vis.insert(s[i][0] - 'a' + 1);
}
int m = s[i].size();
mx = max(mx, m);
int p = 0;
for (int j = m - 1; j >= 0; j--)
num[++p][s[i][j] - 'a' + 1]++;
}
mx += 10;
for (int i = 1; i <= mx; i++)
{
for (int j = 1; j <= 26; j++)
{
num[i + 1][j] += num[i][j] / 26;
num[i][j] %= 26;
}
}
mx++;
for (int j = 1; j <= 26; j++)
{
tt[j].x = j;
for (int i = mx; i >= 1; i--)
{
tt[j].s2 += num[i][j] + 'a' - 1;
}
// cout << s2[j] << endl;
}
sort(tt + 1, tt + 1 + 26);
int ct = 0;
for (int i = 1; i <= 26; i++)
{
if (!vis.count(tt[i].x))
{
val[tt[i].x] = ct++;
break;
}
}
for (int i = 1; i <= 26; i++)
if (!val.count(tt[i].x))
val[tt[i].x] = ct++;
printf("Case #%d: %lld\\n", ++CA, get());
// for (int i = 1; i <= 26; i++)
// cout << i << ' ' << val[i] << endl;
}
int main()
{
// freopen("hack.txt", "r", stdin);
// freopen("out2.txt", "w", stdout);
while (cin >> n)
solve();
return 0;
}
以上是关于2017北航多校B 思维+大数的主要内容,如果未能解决你的问题,请参考以下文章
HDU6038-Function-数学+思维-2017多校Team01