• AT2067 たくさんの数式 / Many Formulas


    AT2067 たくさんの数式 / Many Formulas

    题目传送门

    题意

    有一个仅由字符1到9构成的字符串S(1≤∣S∣≤10),让你在中间添加+,使其变成一个加式。求所有方案的和值(详见样例解释)。
    输入125,输出176.

    有4种:

    125
    1+25=26
    12+5=17
    1+2+5=8
    

    题解

    (驳回无脑暴搜)
    看到题目直接想到的就是
    对于字符串中的每一段数字分别计算贡献再求和
    每一段数字的贡献就是 数值*安排加号的方案数(该数值两边的加号已经安排好了)
    对于一个长为tot的序列 中间可以插入加号的的空为(tot-1)个
    那么对于一段长为len的数字 它安排加号方案数的计算方法如下:
    情况一:该段数字并没有处在边界上(没有拿第一位数字或者最后一位数字)
    1.该段数字使得其内部无法填入加号,坑位减少(len-1)个;
    2.该段数字两边无法填入加号,坑位减少2个;
    3.合计减少坑位(len+1)个。
    剩余坑位为(tot-1-len-1)=(tot-len-2)个
    情况二:该段数字处在边界上
    1.内部无法填入加号,坑位减少(len-1)个;
    2.该段数字的一边无法填入加号(另一边是边界,本来就没得坑位),坑位减少1个;
    3.合计减少坑位(len)个。
    剩余坑位为(tot-1-len)=(tot-len-1)个。
    那么知道坑位个数就可以算出方案数了吧
    对于每个坑可以填也可以不填,所以方案数就是2^(坑数)。
    最后累加就行了。
    还有一个关键点就是如何枚举每一段数字,这里我的方法是先枚举长度,再枚举起点。
    (时间比别的代码好像快那么几毫秒,纯粹是赢在算法上?)

    代码

    #include <cstdio>
    #define ll long long
    using namespace std;
    inline ll read(){
    	ll x=0,f=1;char c=getchar();
    	while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
    	while (c>='0'&&c<='9') {x=(x<<1)+(x<<3)+(c^48);c=getchar();}
    	return x*f;
    }
    int a[20],q[20];
    int tot;
    ll ans;
    
    signed main(){
    	ll b=read();
    	while (b){
    		q[++tot]=b%10;
    		b/=10;
    	}
    	for (int i(1);i<=tot;++i) a[i]=q[tot-i+1];//可能这一步还有更优处理。
    	for (int l(1);l<=tot;++l)
    		for (int i(1);i+l-1<=tot;++i){
    			ll num=0;
    			for (int j(i);j<=i+l-1;++j) num*=10,num+=a[j];
    			//printf("%lld ",num);
    			if (i==1||i+l-1==tot){//靠在边界上
    				for (int i(1);i<=tot-l-1;++i) num*=2;
    				ans+=num;
    			}
    			else {//没靠在边界上
    				for (int i(1);i<=tot-l-2;++i) num*=2;
    				ans+=num;
    			}
    		}
    	printf("%lld",ans);
    	return 0; 
    }
    
    
  • 相关阅读:
    『嗨威说』算法设计与分析
    『嗨威说』算法设计与分析
    『嗨威说』算法设计与分析
    『嗨威说』算法设计与分析
    『嗨威说』数据结构
    『嗨威说』数据结构
    『嗨威说』数据结构
    『嗨威说』数据结构
    『嗨威说』数据结构
    『嗨威说』数据结构的基本概念和术语、算法分析的时间复杂度(深度剖析)
  • 原文地址:https://www.cnblogs.com/cancers/p/11605067.html
Copyright © 2020-2023  润新知