POJ 2718簡單列舉貪心演算法(好久沒寫程式碼了。。)

果7發表於2014-01-08
Smallest Difference
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 3230   Accepted: 909

Description

Given a number of distinct decimal digits, you can form one integer by choosing a non-empty subset of these digits and writing them in some order. The remaining digits can be written down in some order to form a second integer. Unless the resulting integer is 0, the integer may not start with the digit 0. 

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

The first line of input contains the number of cases to follow. For each case, there is one line of input containing at least two but no more than 10 decimal digits. (The decimal digits are 0, 1, ..., 9.) No digit appears more than once in one line of the input. The digits will appear in increasing order, separated by exactly one blank space.

Output

For each test case, write on a single line the smallest absolute difference of two integers that can be written from the given digits as described by the rules above.

Sample Input

1
0 1 2 4 6 7

Sample Output

28


給你N個不同的數字(0~9),用他們組成兩個數字,不能0開頭,使得他們的差最小,問最小的差值是多少。

解題思路:

分兩種情況討論:
     N為even時,列舉兩個靠得最近的數字作為最高位,最高位較高的然後後面依次放最小的,最高位較底的然後後面依次放最大的。貪心思想。
N為odd時,先選一個最小的數字作為位數多的數字的最高位,然後後面依次放較小的,再在另一個數字最大到最低從高到低位放。

題目地址:Smallest Difference

AC程式碼:
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<string>
using namespace std;
char str[1000005];
int a[10],m;
int visi[10];
int res1,res2;
int flag;

void dfs1(int p,int step)
{
    if(flag) return;
    if(step==m/2)
    {
        res1 = min(res1,p);
        flag=1;
        return ;
    }
    for(int i=0; i<=9; i++)
    {
        if(flag) return;
        if(a[i]&&!visi[i])
        {
            visi[i]=1;
            dfs1(p*10+i,step+1);
        }
    }
}

void dfs2(int p,int step)
{
    if(step==m/2)
    {
        res2 = max(res2,p);
        return ;
    }
    for(int i=9; i>=0; i--)
    {
        if(a[i]&&!visi[i])
        {
            visi[i]=1;
            dfs2(p*10+i,step+1);
        }
    }
}

int solve()
{
    int i,j,num1,num2,ans;
    ans = 1e9;
    if(m%2==0)
    {
        if(m==2&&a[0]==1)    //包含0的時候
        {
            for(i=1; i<=9; i++)
                if(a[i])
                    return i;
        }
        for(i=9; i>1; i--) //選首位
        {
            memset(visi,0,sizeof(visi));
            res1 = 1e9 , res2=-1;
            if(a[i])
            {
                visi[i]=1;
                num1=i;
                int tt=0;
                for(j=i-1; j>0; j--) //選首位
                {
                    if(a[j])
                    {
                        visi[j]=1;
                        num2=j;
                        tt=1;
                        break;
                    }
                }

                if(!tt) continue;
                flag=0;
                dfs1(num1,1);
                dfs2(num2,1);
                //cout<<res1<<" "<<res2<<endl;
                ans = min(res1-res2,ans);
            }
        }
    }
    else
    {
        memset(visi,0,sizeof(visi));
        int t1=1,t2=1;
        for(i=1; i<=9; i++)
        {
            if(a[i])
            {
                visi[i]=1;
                num1=i;
                break;
            }
        }
        for(j=9; j>=0; j--)
        {
            if(a[j])
            {
                visi[j]=1;
                num2=j;
                break;
            }
        }
        for(i=0;i<=9;i++)
        {
            if(t1==m/2+1) break;
            if(a[i]&&!visi[i])
            {
                visi[i]=1;
                num1=num1*10+i;
                t1++;
            }
        }
        for(i=9;i>=0;i--)
        {
            if(t2==m/2) break;
            if(a[i]&&!visi[i])
            {
                visi[i]=1;
                num2=num2*10+i;
                t2++;
            }
        }
        ans = num1-num2;
    }

    return ans;
}

int main()
{
    int t,i;
    cin>>t;
    gets(str);
    while(t--)
    {
        m=0;
        memset(a,0,sizeof(a));
        gets(str);
        for(i=0; i<strlen(str); i++)
        {
            if(str[i]>='0'&&str[i]<='9')
            {
                a[str[i]-'0']++;
                m++;
            }
        }
        int res = solve();
        cout<<res<<endl;
    }
    return 0;
}

/*
25
0 1 2 4 6 7
2 4
*/



相關文章