题意:
给出6个数,可以任意做四则运算,但是每个数和每个等式的结果只能用一次,任何时候运算结果都要求是正整数。问能否能得出指定的值,如果不能,要求得到最接近的值。要求输出解,不要所有数字都用上,也不要求输出的过程个个都有用。
题解:
每次枚举剩下的数和结果里选两个枚举运算方式,将结果放进去再dfs。
做之前先把6个数排序,如果两次枚举的数和上次一样,就不用再做了。加上这个剪枝可以快很多。本来想插入新结果再排序的,不过效果反而差。
//Time:3869ms
//Memory:0KB
//Length:2370B
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <queue>
#include <cstring>
#include <algorithm>
using namespace std;
#define MAXN 710
#define MAXM 60010
#define MOD 1000000007
#define INF 1000000007
#define FI first
#define SE second
struct _node
{
int a,b,c;
long long d;
void init(int aa,int bb,int cc,long long dd)
{
a=aa,b=bb,c=cc,d=dd;
}
};
const char ope[10]="+-*/";
int tar,top;
long long best,num[10];
_node sta[10];
_node ans[10];
void upd(int h,long long now)
{
for(int i=0;i<h;++i)
ans[i]=sta[i];
best=now;
top=h;
}
void print()
{
printf("Target: %d\n",tar);
for(int i=0;i<top;++i)
{
printf("%d %c %d = %lld\n",ans[i].a,ope[ans[i].b],ans[i].c,ans[i].d);
}
printf("Best approx: ");
cout<<best<<"\n\n";
}
bool dfs(int h,long long arr[])
{
for(int i=0;i<h;++i)
{
if(arr[i]==tar)
{
upd(6-h,arr[i]);
return true;
}
else if(abs(best-tar)>abs(tar-arr[i]))
upd(6-h,arr[i]);
}
if(h==1) return false;
long long tmp[6];
bool flag=0;
for(int i=0;i<h&&!flag;++i)
for(int j=0;j<h&&!flag;++j)
if(i!=j&&(j==0||arr[j]!=arr[j-1]))
for(int k=0;k<4&&!flag;++k)
{
for(int l=0,cnt=0;l<h;++l)
if(l!=i&&l!=j) tmp[cnt++]=arr[l];
if(k==0)
tmp[h-2]=arr[i]+arr[j],sta[6-h].init(arr[i],k,arr[j],tmp[h-2]),flag=dfs(h-1,tmp);
if(!flag&&k==1&&arr[i]>arr[j])
tmp[h-2]=arr[i]-arr[j],sta[6-h].init(arr[i],k,arr[j],tmp[h-2]),flag=dfs(h-1,tmp);
if(!flag&&k==2)
tmp[h-2]=arr[i]*arr[j],sta[6-h].init(arr[i],k,arr[j],tmp[h-2]),flag=dfs(h-1,tmp);
if(!flag&&k==3&&(arr[i]%arr[j]==0))
tmp[h-2]=arr[i]/arr[j],sta[6-h].init(arr[i],k,arr[j],tmp[h-2]),flag=dfs(h-1,tmp);
}
return flag;
}
int main()
{
//freopen("/home/moor/Code/input","r",stdin);
int ncase;
scanf("%d",&ncase);
for(int hh=1;hh<=ncase;++hh)
{
for(int i=0;i<6;++i) scanf("%lld",&num[i]);
scanf("%d",&tar);
best=INF;
sort(num,num+6);
dfs(6,num);
print();
}
return 0;
}