HDU4403-模拟、数学

一道很难的奥数题,给出一个数字串,插入加号和等号使之成立。求成立的算式数。

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

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

 1 #include <algorithm>
 2 #include <cstring>
 3 #include <ctype.h>
 4 #include <cstdlib>
 5 #include <cstdio>
 6 #include <vector>
 7 #include <string>
 8 #include <queue>
 9 #include <stack>
10 #include <cmath>
11 #include <set>
12 #include <map>
13 
14 using namespace std;
15 
16 int N,M,T;
17 char save[20];
18 
19 map <long long,int> m[2];
20 
21 void solve(int l,int r,long long cur,long long combo,int d)
22 {
23     if(l >= r)
24     {
25         cur += combo;
26         if(m[d].count(cur) == 0)
27             m[d].insert( pair<long long,int>(cur,1));
28         else m[d][cur]++;
29         return;
30     }
31     
32     solve(l+1,r,cur+combo,save[l+1]-'0',d);
33     solve(l+1,r,cur,combo*10+save[l+1]-'0',d);
34     return;
35 }
36 
37 int main()
38 {
39     while(scanf("%s",save) && save[0] != 'E')
40     {
41         int n = strlen(save);
42         int ans = 0;
43         for(int i = 0;i < n-1;i++)
44         {
45             m[0].clear();m[1].clear();
46             solve(0,i,0,save[0]-'0',0);
47             solve(i+1,n-1,0,save[i+1]-'0',1);
48             map<long long,int>::iterator it = m[0].begin();
49             
50             for(;it != m[0].end();it++)
51             {
52                 //printf("%d %d\n",it->first,it->second);
53                 if(m[1].count(it->first) )
54                     ans += (it->second * m[1][it->first]);
55             }
56         }
57         printf("%d\n",ans);
58     }
59 }

 

posted @ 2015-09-08 20:30  Helica  阅读(424)  评论(0编辑  收藏  举报