题目链接:A very hard Aoshu problen
解题思路:今年广州现场赛感觉就是一模一样的题目,这这这。。。。直接用二进制进行广搜。我们设置由n个数,那么这n个数就有n - 1个位置放置+号,我们将n和数分成a,b两段,a + b = n,那么就有a - 1, b - 1个位置放置加号,那么用二进制把这些位都压缩了,1表示放+,0表示不放。那么我们不用DFS直接一个循环就搞定了。剩下的就是枚举+号了。然后记录左一半和右一半解相等的数量有多少。
#include<string>
#include<iostream>
#include<map>
#define ll long long
using namespace std;
string s;
int ans;
map<ll, int> num;
ll get(ll t, int a, int b){
ll ret = 0, tem = 0, i = 0;
while(t){
tem = tem * 10 + (s[a + i] - '0');
if(t & 1){
ret += tem;
tem = 0;
}
t >>= 1;
i++;
}
tem = 0;
for(; a + i <= b; i++){
tem = tem * 10 + (s[a + i] - '0');
}
return ret + tem;
}
int main(){
int i;
ll j, k;
while(cin >> s){
if(s == "END") break;
ans = 0;
for(i = 0; i < s.length() - 1; i++){
num.clear();
for(j = 0; j < (1L << i); j++){
//printf("%I64d %I64d\n", j, get(j, 0, i));
num[get(j, 0, i)]++;
}
for(j = 0; j < (1L << (s.length() - 2 - i)); j++){
//printf("%I64d %I64d\n", j, get(j, i + 1, s.length() - 1));
ans += num[get(j, i + 1, s.length() - 1)];
}
}
printf("%d\n", ans);
}
return 0;
}