POJ 2718 Smallest Difference (dfs)

题目大意:就是在给出的几个数中,分成两个排列,使之组合后  两个序列所对应的值的差最小


思路:直接枚举一半,然后枚举组合数,简单暴力。


注意题目中说的 ,除非是这个数一定为0   不然不能用0开头。就是下面两个数据

5

0 2 3

0 2



分别输出的是17 和 2

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <vector>
#include <cstring>
using namespace std;

vector<int>M;
int lef[10];
int rig[10];
bool vis[10];
int n;
int ans;

int getval1(int len)
{
    int val=0;
    if(lef[0]==0 && len!=1)return 0x3f3f3f3f;
    for(int i=0;i<len;i++)
    val=val*10+lef[i];

    return val;
}

int getval2(int len)
{
    int val=0;
    if(rig[0]==0 && len!=1)return 0x3f3f3f3f;

    for(int i=0;i<len;i++)
    val=val*10+rig[i];
    return val;
}

void dfs2(int len)
{
    int top1=0;
    int top2=0;

    for(int i=0;i<M.size();i++)
    {
        if(vis[i])lef[top1++]=M[i];
        else rig[top2++]=M[i];
    }


    /*for(int i=0;i<top1;i++)
    printf("%d ",lef[i]);
    puts("");

    for(int i=0;i<top2;i++)
    printf("%d ",rig[i]);
    puts("");*/
    do
    {
        int val1=getval1(top1);
        do
        {
            int val2=getval2(top2);
            if(abs(val1-val2)<ans)
            {
               // printf("%d %d\n",val1,val2);
                ans=abs(val1-val2);
            }
        }while(next_permutation(rig,rig+top2));
    }while(next_permutation(lef,lef+top1));
}

void dfs1(int len,int pos,int dep)
{
    if(dep>len)
    {
       // for(int i=0;i<M.size();i++)
        //if(vis[i])printf("%d ",M[i]);
        //puts("");

        dfs2(len);
        return;
    }
    for(int i=pos;i<n;i++)
    {
        vis[i]=true;
        dfs1(len,i+1,dep+1);
        vis[i]=false;
    }
}


int main()
{
    int T;
    scanf("%d",&T);
    getchar();
    while(T--)
    {
        M.clear();
        memset(vis,false,sizeof vis);
        ans=0x3f3f3f3f;
        char ch;
        int a;
        do
        {
            scanf("%d%c",&a,&ch);
            M.push_back(a);
        }while(ch!='\n');

       /* for(int i=0;i<M.size();i++)
        printf("%d ",M[i]);*/


        n=M.size();

        dfs1(n/2,0,1);


        printf("%d\n",ans);
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值