HDU 4403
题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=4403
题意:
对于一个数字串(长度小于等于15),问有多少种添加一个等号和多个或者0个+号的方法,使得等号两边值相等。
思路:
暴搜,枚举=号位置后,枚举每次有几个加号,然后这些加号放的位置。
源码:
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <iostream>
#include <iomanip>
#include <sstream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <ctime>
#include <climits>
#include <cassert>
#include <cmath>
#include <string>
#include <bitset>
#include <vector>
#include <deque>
#include <list>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <algorithm>
#include <functional>
#include <utility>
#include <numeric>
#define LL long long
#define gmax(a,b) ((a) > (b) ? (a) : (b))
#define gmin(a,b) ((a) < (b) ? (a) : (b))
#define MOD (1000000007)
using namespace std;
const int MAXN = 20;
char str[MAXN];
map<LL,LL>mm, mn;
LL ans;
int vis[MAXN];
void dfs1(int l, int r, int num)
{
if(num == 0){
LL lv = 0;
LL temp = str[0] - '0';
for(int i = 0 ; i < r ; i++){
if(vis[i] == 0) temp = temp * 10 + str[i + 1] - '0';
else lv += temp, temp = str[i + 1] - '0';
}
// for(int i = 0 ; i < r ; i++)
// printf("vis[%d] = %d\n", i, vis[i]);
// if(vis[r] == 1) printf("rhuasdad\n");
lv += temp;
mm[lv]++;
// printf("l = %d, r = %d, lv = %I64d\n", 0, r, lv);
return;
}
for(int i = l ; i <= r - num ; i++){
vis[i] = 1;
dfs1(i + 1, r, num - 1);
vis[i] = 0;
}
}
void solve1(int l, int r)
{
int num = r - l;
for(int i = 0 ; i <= num ; i++){
dfs1(0, r, i);
}
}
void dfs2(int now, int l, int r, int num)
{
if(num == 0){
LL lv = 0;
LL temp = str[l] - '0';
for(int i = l ; i < r ; i++){
if(vis[i] == 0) temp = temp * 10 + str[i + 1] - '0';
else lv += temp, temp = str[i + 1] - '0';
}
// if(vis[r] == 1) printf("rhuasdad\n");
// for(int i = l ; i <= r ; i++)
// printf("vis[%d] = %d\n", i, vis[i]);
lv += temp;
// printf("l = %d, r = %d, lv = %I64d\n", l, r, lv);
// mn[lv]++;
// if(mm[lv]) printf("lv = %I64d\n", lv);
// ans += mn[lv] * mm[lv];
ans += mm[lv];
return;
}
for(int i = now ; i <= r - num; i++){
vis[i] = 1;
dfs2(i + 1, l, r, num - 1);
vis[i] = 0;
}
}
void solve2(int l, int r)
{
int num = r - l + 1;
for(int i = 0 ; i < num ; i++){
dfs2(l, l, r, i);
}
}
int main()
{
// freopen("1004.in", "r", stdin);
while(scanf("%s", str) != EOF && str[0] != 'E'){
int len = strlen(str);
ans = 0;
memset(vis, 0, sizeof(vis));
for(int i = 0 ; i < len - 1 ; i++){
mm.clear();
mn.clear();
// dfs1(0, i, str[0] - '0');
// dfs2(i + 1, len - 1, str[i + 1] - '0');
solve1(0, i);
solve2(i + 1, len - 1);
// printf("\n");
}
printf("%I64d\n", ans);
}
return 0;
}