HDU-4403 A very hard Aoshu problem 枚举
直接枚举等号所在位置,然后左右两边用两个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; }