POJ 2718 Smallest Difference

暴力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;
}

 

posted @ 2016-03-30 14:43  Fighting_Heart  阅读(165)  评论(0编辑  收藏  举报