poj 2718

来源:互联网 发布:网络优化工程师待遇 编辑:程序博客网 时间:2024/05/21 20:05

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

思路:得到最小差的数是有规律的,两个数总是在数列中部(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 0xfffffffusing 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;}


原创粉丝点击