2017 Multi-University Training Contest - Team 1 Balala Power!

4 篇文章 0 订阅
2 篇文章 0 订阅

这个算法没啥好说的,排序,贪心,注意不能为0的既可以。

但是实现上要注意一些。

首先每个字母开辟一个大的数组,用来储存该字母所占的指数位。weight[]

然后根据指数位进行排序。

然后在将权进行取模即可。

fac[0]=1;
for(int i=1;i<LEN-3;i++)  
    fac[i]=fac[i-1]*26%MOD;

最后累加求出结果。

AC代码

#include<iostream>
		#include<cstdio>
		#include<cstring>
		#include<algorithm>
		using namespace std;
		
		const int LEN=100005;
		const int MOD=1000000007; 
		
		typedef struct node
		{
			char id;
			int my_weight[LEN];
			int value;
			bool iszero;
			
			void bitINC(int bit)
			{
				my_weight[bit]++;
				while(my_weight[bit]==26)
				{
				    my_weight[bit]=0;
					bit++;
					my_weight[bit]++;
				}
			}
			
			friend bool operator<(node &t1,node &t2)
			{
				for(int i=LEN-3;i>=0;i--)
				{
					if(t1.my_weight[i]>t2.my_weight[i])
					    return true;
					else if(t1.my_weight[i]<t2.my_weight[i])
					    return false;
				}
				return false;
			}
		}node;
		node chars[30];
		
		long long fac[LEN];
		void init()
		{
			for(int i=0;i<=25;i++)
			{
				chars[i].id='a'+i;
				memset(chars[i].my_weight,0,sizeof(chars[i].my_weight));
				chars[i].iszero=true;
			}
				
			fac[0]=1;
			for(int i=1;i<LEN-3;i++)  
                fac[i]=fac[i-1]*26%MOD;  	
		}
		
		int main()
{
	    int n,Case=1;
		while(scanf("%d",&n)==1)
		{
			init();
			char instr[LEN];
			for(int i=1;i<=n;i++)
			{
				scanf("%s",instr);
				int s=strlen(instr);
				if(s>=2)
				    chars[instr[0]-'a'].iszero=false;
				for(int i=s-1;i>=0;i--)
				{
					chars[instr[i]-'a'].bitINC(s-1-i);
				}
			}
				
			sort(chars,chars+26);
			
			for(int i=0;i<=25;i++)
				chars[i].value=25-i;		
			if(!chars[25].iszero)
			{
				for(int j=24;j>=0;j--)
				{
					if(chars[j].iszero)
					{
						node temp=chars[j];
						for(int i=j;i<=24;i++)
						{
							chars[i]=chars[i+1];
						}
						chars[25]=temp;
						break;
					}
				}
			}
			for(int i=0;i<=25;i++)
				chars[i].value=25-i;
			
			//debug
			/*for(int i=0;i<=25;i++)
			{
				printf("id=%c iszero=%d value=%d\n",chars[i].id,chars[i].iszero,chars[i].value);
				for(int j=0;j<=30;j++)
				{
					cout<<chars[i].my_weight[j]<<" ";
				}
				cout<<endl<<endl;
			}
			
			for(int u=0;u<50;u++)
			{
			    cout<<fac[u]<<" ";
			}
			cout<<endl<<endl;*/
			
			
			long long ans=0;
			for(int i=0;i<=25;i++)
			{
				for(int j=0;j<LEN-3;j++)
				{
					if(chars[i].my_weight[j]!=0)
					{
						long long sx=chars[i].value*chars[i].my_weight[j]%MOD;
					    sx=sx*fac[j]%MOD;
					    ans+=sx;
					    ans%=MOD;
					}	
				}
			}
			printf("Case #%d: %lld\n",Case++,ans);
		}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值