题目大意:就是在给出的几个数中,分成两个排列,使之组合后 两个序列所对应的值的差最小
思路:直接枚举一半,然后枚举组合数,简单暴力。
注意题目中说的 ,除非是这个数一定为0 不然不能用0开头。就是下面两个数据
5
0 2 3
0 2
分别输出的是17 和 2
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <vector>
#include <cstring>
using namespace std;
vector<int>M;
int lef[10];
int rig[10];
bool vis[10];
int n;
int ans;
int getval1(int len)
{
int val=0;
if(lef[0]==0 && len!=1)return 0x3f3f3f3f;
for(int i=0;i<len;i++)
val=val*10+lef[i];
return val;
}
int getval2(int len)
{
int val=0;
if(rig[0]==0 && len!=1)return 0x3f3f3f3f;
for(int i=0;i<len;i++)
val=val*10+rig[i];
return val;
}
void dfs2(int len)
{
int top1=0;
int top2=0;
for(int i=0;i<M.size();i++)
{
if(vis[i])lef[top1++]=M[i];
else rig[top2++]=M[i];
}
/*for(int i=0;i<top1;i++)
printf("%d ",lef[i]);
puts("");
for(int i=0;i<top2;i++)
printf("%d ",rig[i]);
puts("");*/
do
{
int val1=getval1(top1);
do
{
int val2=getval2(top2);
if(abs(val1-val2)<ans)
{
// printf("%d %d\n",val1,val2);
ans=abs(val1-val2);
}
}while(next_permutation(rig,rig+top2));
}while(next_permutation(lef,lef+top1));
}
void dfs1(int len,int pos,int dep)
{
if(dep>len)
{
// for(int i=0;i<M.size();i++)
//if(vis[i])printf("%d ",M[i]);
//puts("");
dfs2(len);
return;
}
for(int i=pos;i<n;i++)
{
vis[i]=true;
dfs1(len,i+1,dep+1);
vis[i]=false;
}
}
int main()
{
int T;
scanf("%d",&T);
getchar();
while(T--)
{
M.clear();
memset(vis,false,sizeof vis);
ans=0x3f3f3f3f;
char ch;
int a;
do
{
scanf("%d%c",&a,&ch);
M.push_back(a);
}while(ch!='\n');
/* for(int i=0;i<M.size();i++)
printf("%d ",M[i]);*/
n=M.size();
dfs1(n/2,0,1);
printf("%d\n",ans);
}
return 0;
}