杭电多校 1002 Balala Power! 题解报告
来源:互联网 发布:淘宝客服安抚顾客语 编辑:程序博客网 时间:2024/05/22 16:04
题目意思不太好理解
大致说一下
小写字母a-z 中的任何一个字母可以用0-25中的任何一个数字表示
但是每个数字只能对应一个字母
解释一下样例
输入一个数 表示下面会输入几个字符串
然后输入字符串 比如aa bb
a b可以用0-25中的任何一个数字表示 但是 是一个26进制的数
但是要让这个数最大
——26进制转换为10进制的方法——
—1.先看这个26进制的数有多少位 比如123 有三位
—2.然后1*26^2 + 2*26^1 + 3*26^0 = 1*26*26+2*26+3 = 731;
然后a取25 b只能取26
这样aa就是 25*26+25 = 675;
bb就是 24*26+24 = 648;
最后648+675 = 1323;
不知道有没有解释清楚 这题还是大三的学长和我讲解的题意
要注意的就是 0-25任意一个数表示一个字母的时候 是一个26进制的数字 要转换为10进制的数字
所以要做出相应的转换
还有一个前导0的问题 题目要求说 不能有第一个是0的排序 注意
这是思路:
上代码
#include <cstdio>#include <cmath>#include <vector>#include <iostream>#include <set>#include <queue>#include <cstring>#include <algorithm>using namespace std;#define mst(a,b) memset((a),(b),sizeof(a)) // define the reset method #define rush() int T;scanf("%d",&T);while(T--) // define the case statistics methodtypedef long long ll;const int maxn = 100005;const ll mod = 1e9+7;const int INF = 0x3f3f3f;const double eps = 1e-9;int n;char s[maxn];int num[26][maxn];int vis[26];int val[maxn];ll po[maxn];int Max;struct node //{ char xx[maxn]; // deposit the string a-z int id;}e[26];bool cmp(const node &a,const node &b) //对贡献从大到小排序{ for(int i=Max-1; i>=0; i--) // Max the lenght of the string { if(a.xx[i]>b.xx[i]) return 1; if(a.xx[i]<b.xx[i]) return 0; } return 1;}void init() //预处理26^n%mod{ po[0]=1; for(int i=1; i<maxn; i++) { po[i]=(po[i-1]*26)%mod; }}int main(){ //freopen("input.txt","r",stdin); //freopen("output.txt","w",stdout); int n; int cas=1; init(); while(~scanf("%d",&n)) { mst(num,0); mst(vis,0); mst(val,0); for(int i=0; i<n; i++) { scanf("%s",s); int len=strlen(s); if(len>1) //标记这个字母权值不能为零 { vis[s[0]-'a']=1; // one point get } for(int j=len-1; j>=0; j--) //统计每个字母在第几位上有几个 { int o=len-1-j; num[s[j]-'a'][o]++; } Max=max(Max,len); //减少循环,节约时间 } for(int i=0; i<26; i++) { for(int j=0; j<maxn; j++) { if(num[i][j]>=26&&j!=Max-1) //number big than 26,we need to exceed; { num[i][j+1]+=num[i][j]/26; // ? num[i][j]%=26; // exceed } } } for(int i=0; i<26; i++) { for(int j=0; j<Max; j++) { e[i].xx[j]=num[i][j]+'a'; //转化为字符形式,节约内存,如果是int可能会爆内存 } e[i].id=i; } sort(e,e+26,cmp); int pos=-1; for(int i=25;i>=0;i--) //从权值小的开始找权值可以为0的字母 { if(vis[e[i].id]==0) { pos=e[i].id; // sign the e[i].id == 0 break; } } int flag=0; for(int i=0;i<26;i++) //给每个字母附上权值 { if(e[i].id==pos) { val[e[i].id]=0; flag=1; continue; } if(flag==0) //We have sorted the array. val[e[i].id]=25-i; else val[e[i].id]=25-i+1; } ll ans=0; for(int i=0;i<26;i++) { for(int j=0;j<Max;j++) { if(num[i][j]) { ll temp=(ll)num[i][j]*val[i]*po[j]%mod; ans=(ans+temp)%mod; } } } printf("Case #%d: %I64d\n",cas++,ans); } return 0;}
然后晚一点 我会再回来讲解一下这个代码
先说这么多
代码更新了一下
代码是从这个博客转过来的http://blog.csdn.net/my_sunshine26/article/details/76098497
这一题的思路是要按照字母对26进制数的贡献值进行排序 然后按照排序依次从25开始赋值
统计出每个字母在哪一位出现了几次,然后比较每个字母取能对结果产生的贡献大小。
每个字母从最后一位开始,如果个数大于等于26,则向前进位,以此类推,最终只要从最高位的个数开始比较即可。注意要考虑前导 0
解释一下:为什么如果个数大于等于26,则向前进位
因为26进制数 如果有字幕的个数大于26的话乘不了26^26 所以这里要进位处理。
- 杭电多校 1002 Balala Power! 题解报告
- 1002 Balala Power!
- 2017杭电多校联赛-Balala Power!
- Balala Power!
- Balala Power!
- Balala Power
- Balala Power!
- Balala Power!
- 2017 杭电多校联赛 1002 Balala Power!(数字替换字母)HDU 6034
- HDU6034 Balala Power! [贪心]
- HDU6034-Balala Power! 贪心
- HDU-6034 Balala Power!
- [HDU]-6034 Balala Power!
- hdu6034 Balala Power! 贪心
- HDU 6034 Balala Power!
- hdu 6034 Balala Power!
- 【HDU 6034 Balala Power!】
- Balala Power(贪心)
- ssm单文件下载ftp服务器到浏览器
- jdk1.8 新特性之 forEach 循环遍历
- JQuery
- Ceres-Solver学习笔记(2)
- CRM的dev(四)--新增和更新之前,判断是否有字段的值重复
- 杭电多校 1002 Balala Power! 题解报告
- JAVA线程池ThreadPoolExecutor
- JavaSQL配置文件查询条件匹配字段是Date时注意事项
- UVA11134FabledRooks
- 油猴子使用简介
- IXDC2017大会:面对新商业体验,设计师转型三部曲
- 让Android Studio披上 Sublime Text的新衣
- Unity众神之光 单词
- Android_设置应用的Intent属性