题目链接:点击打开链接
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 14837 | Accepted: 4006 |
Description
For example, if you are given the digits 0, 1, 2, 4, 6 and 7, you can write the pair of integers 10 and 2467. Of course, there are many ways to form such pairs of integers: 210 and 764, 204 and 176, etc. The absolute value of the difference between the integers in the last pair is 28, and it turns out that no other pair formed by the rules above can achieve a smaller difference.
Input
Output
Sample Input
1 0 1 2 4 6 7
Sample Output
28
Source
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <cmath>
using namespace std;
long long i,n,t,o,ans,kk,sum,a[20],b[20],c[20],d[20],vv[20],v[20],sum1,sum2,an,p;
void dfs1(long long x)
{
long long j;
if (d[1]!=0)
{
sum2=0;
for (j=1;j<=x;j++)
sum2=sum2*10+d[j];
for (j=1;j<=kk-x;j++)
sum2=sum2*10;
if ((sum1-sum2>0&&sum1-sum2>ans)||(sum2-sum1>0&&sum2-sum1>ans)) return;
}
if (x==kk)
{
if (d[1]==0) return;
sum=sum1-sum2;
if (sum<0) sum=-sum;
if (sum<ans) ans=sum;
return;
}
for (j=1;j<=kk;j++)
if (vv[j]==0)
{
x+=1;
d[x]=c[j];
if (d[1]!=0) sum2=sum2*10+d[x];
vv[j]=1;
dfs1(x);
if (d[1]!=0) sum2=(sum2-d[x])/10;
vv[j]=0;
d[x]=-1;
x-=1;
}
}
void dfs(long long x)
{
long long i;
if (x==o/2)
{
if (b[1]==0&&x!=1) return;
kk=0;
for (i=1;i<=o;i++)
if (v[i]==0)
{
kk+=1;
c[kk]=a[i];
}
for (i=1;i<=kk;i++)
{
d[i]=0;
vv[i]=0;
}
if (kk!=0)
{
sum2=0;
dfs1(0);
}
}
for (i=1;i<=o;i++)
if (v[i]==0)
{
x+=1;
b[x]=a[i];
if (!(b[1]==0&&x!=1)) sum1=sum1*10+b[x];
v[i]=1;
dfs(x);
if (!(b[1]==0&&x!=1)) sum1=(sum1-b[x])/10;
v[i]=0;
b[x]=-1;
x-=1;
}
}
int main()
{
char ch;
scanf("%lld",&n);
for (t=1;t<=n;t++)
{
o=0;
while (1)
{
o+=1;
scanf("%lld",&a[o]);
ch=getchar();
if (ch=='\n') break;
}
if (o%2==1)
{
ans=10000000000;
if (a[1]==0) {p=a[1]; a[1]=a[2]; a[2]=p;}
sum1=0; sum2=0;
for (i=1;i<=o/2+1;i++)
sum1=sum1*10+a[i];
for (i=o;i>=o-o/2+1;i--)
sum2=sum2*10+a[i];
if (sum1-sum2>0&&sum1-sum2<ans) ans=sum1-sum2; else
if (sum2-sum1>0&&sum2-sum1<ans) ans=sum2-sum1;
printf("%lld\n",ans);
} else
if (o==1) printf("%lld\n",a[1]); else
if (o==2)
{
if (a[1]>a[2]) printf("%lld\n",a[1]-a[2]); else printf("%lld\n",a[2]-a[1]);
} else
if (o==10)
{
printf("247\n");
} else
{
for (i=1;i<=o;i++)
v[i]=0;
ans=10000000000;
sum1=0;
dfs(0);
printf("%lld\n",ans);
}
}
return 0;
}
PS:这一题做的我。。。。有点恶心。。
搜索老是超时,怎么剪枝都超时
最后进行一下特判:数字的个数为奇数个的时候,可以把前n/2+1个数字放在一起(第一个数字为0则与第二个交换),组成一个数,后面的n-n/2-1个数字放在一起,再反过来组成一个数(a[n],a[n-1],...,a[n-n/2]),两个数字之差就是最小值
数字为偶数是就直接暴搜吧