您的位置:首页 > Web前端

POJ 2718 Smallest Difference

2016-03-30 14:43 513 查看
暴力DFS。

如果一个数比另一个数位数多,那么位数多的那个数从小到大排序,位数少的从大到小排序,这样能算出这种情况下的最小差值。

如果两个数字位数相同,可以枚举最高位分别是哪个数字,然后就可以确定哪个数字较大,大的那个数剩下的数字从小到大排序,小的那个数字从大到小排序。

注意处理一下前导0的问题。

#include<cstdio>
#include<cstring>
#include<cmath>
#include<vector>
#include<algorithm>
using namespace std;

int T;
char s[1000];
long long a[20];
int tot;
bool flag[20];
long long r[20],t[20];
int lenr,lent;
long long ans;

void read()
{
tot=0;
while(1)
{
char ch=getchar();
if(ch=='\n') break;
if(ch==' ') continue;
a[tot++]=(long long)(ch-'0');
}
}

bool cmp(const long long&a,const long long &b)
{
return a>b;
}

void check()
{
lenr=lent=0;
memset(r,0,sizeof r);memset(t,0,sizeof t);
for(int i=0;i<tot;i++)
{
if(flag[i]==1) r[lenr++]=a[i];
else t[lent++]=a[i];
}

if(lenr<lent)
{
sort(t,t+lent); sort(r,r+lenr,cmp);
if(t[0]==0) swap(t[0],t[1]);
long long sum1=0,sum2=0;
for(int i=0;i<lenr;i++) sum1=sum1*10+r[i];
for(int i=0;i<lent;i++) sum2=sum2*10+t[i];
ans=min(ans,sum2-sum1);
}

else if(lenr==lent)
{
sort(t,t+lent); sort(r,r+lenr);
long long sum1=0,sum2=0;
for(int i=0;i<lenr;i++)
{
for(int j=0;j<lent;j++)
{
if(r[i]==0&&lenr!=1) continue;
if(t[j]==0&&lent!=1) continue;

sum1=r[i];sum2=t[j];
if(r[i]>t[j])
{
for(int k=0;k<lenr;k++)
{
if(r[k]==r[i]) continue;
sum1=sum1*10+r[k];
}

for(int k=lent-1;k>=0;k--)
{
if(t[k]==t[j]) continue;
sum2=sum2*10+t[k];
}

ans=min(ans,sum1-sum2);
}
else
{
for(int k=lenr-1;k>=0;k--)
{
if(r[k]==r[i]) continue;
sum1=sum1*10+r[k];
}

for(int k=0;k<=lent;k++)
{
if(t[k]==t[j]) continue;
sum2=sum2*10+t[k];
}

ans=min(ans,sum2-sum1);
}

}
}

}
}

void dfs(int idx,int deep)
{
check();
if(deep==tot/2) return;
for(int i=idx;i<tot;i++)
{flag[i]=1;dfs(i+1,deep+1);flag[i]=0;}
}

int main()
{
scanf("%d",&T); getchar();
while(T--)
{
read(); ans=999999999999999;
for(int i=0;i<tot;i++)
{flag[i]=1;dfs(i+1,1);flag[i]=0;}
printf("%lld\n",ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: