HDU 4403 A very hard Aoshu problem (状态压缩+枚举)

来源:互联网 发布:seo h1标签 编辑:程序博客网 时间:2024/06/05 07:31

题目链接:HDU 4403 A very hard Aoshu problem

题意:给出一串数字,再数字与数字间插入‘+’,‘=’使之成为一个等式,求等式的个数。

数字最多只有15个。枚举加号的所有状态(2^14,二进制1为 加号,0为空),比较暴力

首先,枚举等号的位置。等号左边为子串A,右边为子串B;

分别在子串A,B中枚举 加号 的状态。

在A中各个状态对应一个等式左边的值,用map记录个数(最大的情况有2的十几次,会爆INT,用map安全点)。

再在枚举B中各个状态时,直接访问map对应是值,求和就是最后的答案。



AC代码:


#include<stdio.h>#include<string.h>#include<string>#include<map>#define ll __int64using namespace std;map<ll,ll> mm;ll a[20];//存+的状态ll ipow(ll a,ll p){ll s=1,i;for(i=0;i<p;i++)s*=a;return s;}void get_two(ll x){int n=0;memset(a,0,sizeof a);while(x){a[n]=x%2;x/=2;n++;}}ll get_subsum(string s,ll x){int len=s.length()-1;ll num=0,sum=0;get_two(x);int j=0;num=s[j++]-'0';for(int i=len-1;i>=0;i--){if(a[i]==0)num=num*10+s[j++]-'0';else{sum+=num;num=s[j++]-'0';}}if(j<len+1)num=num*10+s[j]-'0';sum+=num;return sum;}void find(string s){ll sum;ll len=s.length();sum=ipow(2,len-1);for(int i=0;i<sum;i++)mm[get_subsum(s,i)]++;}ll judge(string s){ll sum,temp;ll len=s.length();sum=ipow(2,len-1);ll ans=0;for(int i=0;i<sum;i++){temp=get_subsum(s,i);ans+=mm[temp];}return ans;}int main(){char str[20];int len,i,j;string a,b;while(scanf("%s",str)!=EOF){if(strcmp(str,"END")==0)break;len=strlen(str);ll ans=0;string c=str;for(j=1;j<len;j++){a=c.substr(0,j);b=c.substr(j,len);find(a);ans+=judge(b);mm.clear();}printf("%I64d\n",ans);}return 0;}/*111123*/



4 0
原创粉丝点击