我直接枚举所有二进制状态(加了点优化),然后bfs爆搜,结果搜1到10这10个数贼快,搜8个10就跟死机了一样.......
不管怎么说,先献上去吧。
#include<bits/stdc++.h>
#define db double
using namespace std;
int n,vis[1<<12],cnt,ans;
struct node
{
int cnt;
db a[11];
node(int n,db *b)
{
cnt=n;
for(int i=1;i<=n;i++)
a[i]=b[i];
}
};
db a[11],b[11];
int bfs()
{
queue<node>q;
q.push(node(cnt,b));
while(!q.empty())
{
node e=q.front();q.pop();
int n=e.cnt;
if(fabs(e.a[n]-24)<1e-9)return 1;
if(e.cnt==1)continue;
for(int i=1;i<n;i++)
for(int j=i+1;j<=n;j++)
{
int tot=1;
for(int k=1;k<=n;k++)
if(k!=i&&k!=j)
b[tot++]=e.a[k];
db x=e.a[i],y=e.a[j];
b[tot]=x*y;
q.push(node(tot,b));
b[tot]=x+y;
q.push(node(tot,b));
b[tot]=x-y;
q.push(node(tot,b));
b[tot]=y-x;
q.push(node(tot,b));
if(x!=0)
{
b[tot]=y/x;
q.push(node(tot,b));
}
if(y!=0)
{
b[tot]=x/y;
q.push(node(tot,b));
}
}
}
return 0;
}
int ok(int s)
{
cnt=0;
for(int j=0;(1<<j)<=s;j++)
if((1<<j)&s)
b[++cnt]=a[j+1];
return bfs();
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
cin>>a[i];
for(int i=0;i<(1<<n);i++)
{
int flag=0;
for(int j=2;j<i;j++)
if(vis[j]&&((i&j)==j))
{
flag=1;
break;
}
if(flag)
{
ans++;
continue;
}
if(ok(i))
vis[i]=1,ans++;
}
printf("%d\n",ans);
}