先判断所有的数字能否分成左右相等的两部分。
这里需要判断和的奇偶还有能否用左边的数量表示和的一半,如果不可以就是impossible。
然后将所有数字分成左右两部分,移项就可以。
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <vector>
#include <map>
#include <string>
#include <algorithm>
#define MAXN 1005
#define MOD 1000000007
#define INF 2139062143
#define ll long long
using namespace std;
vector<int> vec;
int sum,a,b;
bool use[20];
bool dfs(int k,int cnt,int val)
{
if(cnt==a)
{
if(val==sum/2)return true;
return false;
}
if(k>=vec.size()) return false;
if(dfs(k+1,cnt+1,val+vec[k]))
{
use[k]=true;
return true;
}
if(dfs(k+1,cnt,val))
{
use[k]=false;
return true;
}
return false;
}
int main()
{
char str[MAXN];
while(gets(str))
{
bool eq=false,op=true,dig=false;
a=0,b=0;
vec.clear();
int L=strlen(str),val=0;
for(int i=0; i<L; ++i)
{
if(isdigit(str[i]))
{
dig=true;
val=val*10+str[i]-'0';
}
if(!isdigit(str[i])||i==L-1)
{
if(str[i]=='=')
{
eq=true;
op=true;
}
else if(str[i]=='-') op=false;
else if(str[i]=='+') op=true;
else if(dig&&(str[i]==' '||i==L-1))
{
if(op==false)
{
if(!eq) b++;
else a++;
}
else
{
if(!eq) a++;
else b++;
}
vec.push_back(val);
dig=false;
}
val=0;
}
}
memset(use,0,sizeof(use));
sum=0;
for(int i=0; i<vec.size(); ++i)
sum+=vec[i];
if(sum%2||!dfs(0,0,0)) puts("no solution");
else
{
vector<int> left,right;
int l=0,r=0;
for(int i=0; i<vec.size(); ++i)
if(use[i]) left.push_back(vec[i]);
else right.push_back(vec[i]);
bool out=false;
op=true;
eq=false;
for(int i=0; i<L; ++i)
{
if(!out&&isdigit(str[i]))
{
out=true;
if(!eq)
{
if(op) printf("%d",left[l++]);
else printf("%d",right[r++]);
}
else
{
if(!op) printf("%d",left[l++]);
else printf("%d",right[r++]);
}
}
if(!isdigit(str[i]))
{
out=false;
putchar(str[i]);
if(str[i]=='=')
{
eq=true;
op=true;
}
else if(str[i]=='-') op=false;
else if(str[i]=='+') op=true;
}
}
printf("\n");
}
}
return 0;
}