poj 2718

16 篇文章 1 订阅

题意:一组数分成两个数得到最小差~

思路:得到最小差的数是有规律的,两个数总是在数列中部(n/2)截取,使用DFS得到组合数,功能相当于next_permutation,但是更自由,可以求得前面的组合之后对后面再进行进一步的操作。

            还有一个超时问题:一开始是得到一个数列的组合之后再从中间进行切割得到两数,但是超时了0.0.....后来采用的方法是将前面的数在 DFS中得到固定,在函数work中对后面(n-n/2)个数进行排列组合。

 

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<cstring>
#include<algorithm>
#define inf 0xfffffff
using namespace std;
string s;
int ans,k,sum,vis[11],num[11];
void dfs(int an)
{
    int d[12]={0};
    int m=0;
    for(int i=0;i<k;i++)
        if(vis[i]==0)
            d[m++]=num[i];
    do
    {
        int b=0;
        for(int i=0;i<m;i++)
        {
            b=b*10+d[i];
        }
        if(m==1 || d[0]!=0)
           ans=min(ans,max(an-b,b-an));
    }while(next_permutation(d,d+m));
}
void DFS(int t)
{
    if(t>=k/2)//>=
      {
        dfs(sum);
        return ;
      }
    for(int i=0;i<k;++i)
    {
         if(vis[i])
            continue;
        if(sum==0&&num[i]==0)
            continue;
        vis[i]=1;
        sum=sum*10+num[i];
        DFS(t+1);
        sum=(sum-num[i])/10;//回溯时用到
        vis[i]=0;
    }
    return ;
}
int main()
{
    int t;
    cin>>t;
    getchar();//如果用scanf()输入的话就不用getchar()了,,
    while(t--)
    {

        //cin>>s;
       getline(cin,s);
        memset(vis,0,sizeof(vis));
        k=0;
        for(int i=0;i<s.length();++i)
            if(s[i]>='0'&&s[i]<='9')
            num[k++]=s[i]-'0';
        int sum=0;
        ans=inf;
        DFS(0);
        cout<<ans<<endl;
    }
    return 0;
}

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值