您的位置:首页 > 其它

HDU4403-模拟、数学

2015-09-08 20:30 253 查看
一道很难的奥数题,给出一个数字串,插入加号和等号使之成立。求成立的算式数。

我的做法是,先分成两段,中间插入等号 ,再分别求出左右两边可能的值和个数,然后对比,把值相等的情况乘起来,加到最终结果上。

求可能值用递归,每次遇到一个数就选择是插入加号还是不插入,不插入加号就把之前维护的值乘以10加上此值,插入加号把维护的值加到和里。这样可以把所有的情况存进map里。

#include <algorithm>
#include <cstring>
#include <ctype.h>
#include <cstdlib>
#include <cstdio>
#include <vector>
#include <string>
#include <queue>
#include <stack>
#include <cmath>
#include <set>
#include <map>

using namespace std;

int N,M,T;
char save[20];

map <long long,int> m[2];

void solve(int l,int r,long long cur,long long combo,int d)
{
if(l >= r)
{
cur += combo;
if(m[d].count(cur) == 0)
m[d].insert( pair<long long,int>(cur,1));
else m[d][cur]++;
return;
}

solve(l+1,r,cur+combo,save[l+1]-'0',d);
solve(l+1,r,cur,combo*10+save[l+1]-'0',d);
return;
}

int main()
{
while(scanf("%s",save) && save[0] != 'E')
{
int n = strlen(save);
int ans = 0;
for(int i = 0;i < n-1;i++)
{
m[0].clear();m[1].clear();
solve(0,i,0,save[0]-'0',0);
solve(i+1,n-1,0,save[i+1]-'0',1);
map<long long,int>::iterator it = m[0].begin();

for(;it != m[0].end();it++)
{
//printf("%d %d\n",it->first,it->second);
if(m[1].count(it->first) )
ans += (it->second * m[1][it->first]);
}
}
printf("%d\n",ans);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: