开始做这个题的时候想着用高精度保存每个字母对和的贡献,开个26位高精度就好了
然后当时就特别困,高精度也是很久以前写的了,就很丢脸的没怼出来
现在补一下题
思路其实还是高精度,但是没有必要拿那种真正的高精度去怼他直接看代码就能理解了
其实这题还是有点练编程能力的
#include <cmath>
#include <algorithm>
#include <cstring>
#include <string>
#include <iostream>
#define Mod 1000000007
#define maxn 100100
#define ll long long
using namespace std;
string s[101000];
ll qz[30][101000];
ll prezero[30];
ll Pow[101000];
void eazy(ll i)//高精度进位
{
ll li=qz[i][0];
for (ll k=1;k<=li;k++)
{qz[i][k+1]+=(qz[i][k]/26);qz[i][k]=qz[i][k]%26;}
for (ll k=li+1;k<maxn;k++)
{
if (qz[i][k]!=0)
{qz[i][k+1]+=(qz[i][k]/26);qz[i][k]=qz[i][k]%26;}
else
{qz[i][0]=k-1;break;}
}
return;
}
bool check(ll i,ll j)//高精度比较大小,如果i比j小返回1,否则返回0
{
if (qz[i][0]>qz[j][0]) return 0;
else if (qz[i][0]<qz[j][0]) return 1;
ll len=qz[i][0];
for (ll k=len;k>0;k--)
if (qz[i][k]>qz[j][k]) return 0;
else if (qz[i][k]<qz[j][k]) return 1;
return 0;
}
int main()
{
ll n,Case(0);
Pow[0]=1;
for (ll k=1;k<=100010;k++)
Pow[k]=(Pow[k-1]*26)%Mod;//打表打表
while(~scanf("%lld",&n))
{
memset(qz,0,sizeof(qz));
memset(prezero,0,sizeof(prezero));
for (ll k=1;k<=n;k++)
{
cin>>s[k];
ll len=s[k].length();
prezero[s[k][0]-'a']=1;
for (ll i=0;i<len;i++)//从最高位到最低位遍历
{
qz[s[k][i]-'a'][len-i]+=1;//1为最低位len为最高位
qz[s[k][i]-'a'][0]=max(qz[s[k][i]-'a'][0],len-i);//qz[][1]为最低位qz[][0]为最高位要遍历到纳
}
}
for (ll k=0;k<26;k++)
{
qz[k][maxn+1]=k;//因为排序会改变顺序嘛,那就在maxn+1上去保存一下
eazy(k);
}
for (ll i=0;i<26;i++)
for (ll j=i+1;j<26;j++)
{
if (check(i,j))//如果i比j小
{
ll lenm=max(qz[i][0],qz[j][0]);
for (ll k=0;k<=lenm;k++)
swap(qz[i][k],qz[j][k]);
swap(qz[i][maxn+1],qz[j][maxn+1]);
}
}//已经从大到小排好序了
//接下来就是赋值然后算答案了
ll bo(0);
for (ll k=25;k>=0;k--)//这个就是把能被赋值为0的权值最小的赋为0其他的按权值大小从25到1进行赋值
{
if (!bo)
if (!prezero[qz[k][maxn+1]]) {qz[k][maxn+2]=0;bo=1;}
else qz[k][maxn+2]=25-k+1;
else qz[k][maxn+2]=25-k;//把赋的值保存在maxn+2上
}
ll ans(0);
for (ll k=0;k<26;k++)
for (ll i=1;i<=qz[k][0];i++)
{
ans=(ans+(((qz[k][maxn+2]*qz[k][i])%Mod)*Pow[i-1])%Mod)%Mod;
}
/* for (int k=0;k<26;k++)
{
cout<<qz[k][maxn+1]<<" "<<qz[k][maxn+2]<<" "<<":";
for (int i=1;i<=qz[k][0];i++)
cout<<qz[k][i]<<" ";
cout<<endl;
}*/
Case++;
printf("Case #%lld: %lld\n",Case,ans);
}
return 0;
}
本文介绍了一种使用高精度计算解决字符串配对问题的方法,通过定制化的高精度算法实现字母对的计数与排序,并最终计算出符合特定规则的字符串配对总和。
945

被折叠的 条评论
为什么被折叠?



