zoukankan      html  css  js  c++  java
  • 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=='
    ') 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
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    202103226-1 编程作业
    阅读任务
    1 20210309-1 准备工作
    20210405-1 案例分析作业
    第一周作业
    20210309-2 阅读任务
    20210309-1 准备工作
    编程作业
    阅读任务
    准备工作
  • 原文地址:https://www.cnblogs.com/zufezzt/p/5337143.html
Copyright © 2011-2022 走看看