Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 1411 Accepted Submission(s): 239
题目链接:HDU 6034
嗯今天多校第一场的一道题由于不知道怎么地把cmp函数写炸了,最后就没写出来。很显然肯定是把最大的系数留给贡献最大的字母,因此贪心地把最大的系数从25-0依次赋值,然后再选取一个最小贡献且不是开头字母的来牺牲一下获得系数0,其他的字母就均不为0了。然后预处理一下26的指数即可,贡献怎么算?一开始按对贡献取模之后排序,后来发现取模之后的排肯定不对,然后用一个结构体记录每一个字母和它出现的位数以及次数,然后手动模拟进位一下,否则比如第0位出现100次肯定比第1位出现1次贡献大(此处要注意可能会进位到maxlen处,比较的时候要多一位,否则WA),最后写一个比较奇怪的cmp函数就可以了,这样就可以正常地排序比较。
代码:
#include <stdio.h>
#include <algorithm>
#include <cstdlib>
#include <cstring>
#include <bitset>
#include <string>
#include <stack>
#include <cmath>
#include <queue>
#include <set>
#include <map>
using namespace std;
#define INF 0x3f3f3f3f
#define LC(x) (x<<1)
#define RC(x) ((x<<1)+1)
#define MID(x,y) ((x+y)>>1)
#define fin(name) freopen(name,"r",stdin)
#define fout(name) freopen(name,"w",stdout)
#define CLR(arr,val) memset(arr,val,sizeof(arr))
#define FAST_IO ios::sync_with_stdio(false);cin.tie(0);
typedef pair<int, int> pii;
typedef long long LL;
const double PI = acos(-1.0);
const int N = 1e5 + 7;
const LL mod = 1e9 + 7;
LL fac[N];
char s[N];
int ishead[30], maxlen;
struct info
{
char c;
LL val;
int f[N];
void init()
{
val = 0LL;
CLR(f, 0);
}
void cal()
{
for (int i = 0; i < maxlen; ++i)
{
if (f[i] >= 26)
{
f[i + 1] += f[i] / 26;
f[i] %= 26;
}
}
}
bool operator<(const info &rhs)const
{
for (int i = maxlen; i >= 0; --i)
{
if (f[i] != rhs.f[i])
return f[i] < rhs.f[i];
}
}
};
info arr[26];
void init()
{
CLR(ishead, 0);
maxlen = 0;
for (int i = 0; i < 26; ++i)
arr[i].init();
}
int main(void)
{
int i, j, n;
fac[0] = 1LL;
for (i = 1; i < N; ++i)
fac[i] = fac[i - 1] * 26LL % mod;
int q = 1;
while (~scanf("%d", &n))
{
init();
for (i = 0; i < n; ++i)
{
scanf("%s", s);
int len = strlen(s);
if (len > 1)
ishead[s[0] - ‘a‘] = 1;
if (len > maxlen)
maxlen = len;
for (j = 0; j < len; ++j)
{
int id = s[j] - ‘a‘;
arr[id].val = (arr[id].val + fac[len - j - 1]) % mod;
++arr[id].f[len - j - 1];
}
}
for (i = 0; i < 26; ++i)
{
arr[i].c = ‘a‘ + i;
arr[i].cal();
}
int sw = 0;
for (i = 0; i < 26; ++i)
{
if (!ishead[arr[i].c - ‘a‘] && arr[i] < arr[sw])
sw = i;
}
swap(arr[0], arr[sw]);
sort(arr + 1, arr + 26);
LL ans = 0;
for (i = 0; i < 26; ++i)
{
ans = ans + (arr[i].val * (LL)(i)) % mod;
ans %= mod;
}
printf("Case #%d: %I64d\n", q++, ans);
}
return 0;
}
原文:http://www.cnblogs.com/Blackops/p/7236709.html