您的位置:首页 > 其它

HDU-4403 A very hard Aoshu problem 枚举

2012-09-22 21:07 441 查看
直接枚举等号所在位置,然后左右两边用两个MAP来记录组成和的个数,然后运用乘法原理得到答案。

代码如下:

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<queue>
#include<set>
#include<map>
#include<cstring>
#include<vector>
#include<string>
#define LL long long
using namespace std;

char s[20];

int len;

map<long long,int>fmp, tmp;

long long get(int x, int y) {
long long ret = 0;
for (int i = x; i <= y; ++i) {
ret = ret * 10 + s[i] - '0';
}
return ret;
}

void cal(int a, int b, map<long long,int>&mp) {
if (a == b) {
++mp[s[a]-'0'];
return;
}
int mask = 1 << (b-a), last;
for (int i = 0; i < mask; ++i) {
long long temp = 0;
last = a;
for (int j = 0; j < (b-a); ++j) {
if (i & (1 << j)) {
temp += get(last, a + j);
last = a + j + 1;
}
}
temp += get(last, b);
++mp[temp];
}
}

long long solve(int x) {
long long ret = 0;
fmp.clear(), tmp.clear();
map<long long, int>::iterator it;
cal(0, x, fmp);
cal(x+1, len-1, tmp);
for (it = fmp.begin(); it != fmp.end(); ++it) {
ret += (long long)(it->second) * (long long)tmp[it->first];
}
return ret;
}

int main(  )
{
long long ret;
while (scanf("%s", s), s[0] != 'E') {
ret = 0;
len = strlen(s);
for (int i = 0; i <= len-2; ++i) {
// 枚举等号所在的位置
ret += solve(i);
}
printf("%I64d\n", ret);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: