poj 2718

链接:http://poj.org/problem?id=2718
题意:给定一堆数 , 分成两堆并内部任意组合成两个数。我们要求两个数的最小差值(不允许前导0)。

我是用dfs 暴搜 , 剪了一下枝(如果中间是第一个数小于第二个数(位数不足补零 && minn < 两数之差时剪枝)) , 我看别人用STL全排列只写了30多行 , dfs 的不过是五六十行 , 我这代码都不好意思贴上来了。。

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <cmath>
#include <map>
using namespace std;
typedef long long ll;
int num[10]; int arr[15] , minn;
void dfs(int step, int len);
int main()
{
   int t,i,j;
   char str[100];
   scanf("%d",&t);
   getchar();
   while(t--)
   {
       gets(str);
       int len = strlen(str) , number = 0;
       memset(num,0,sizeof(num));
       for(i=0; i<len; i++)
       {
           if(str[i]>='0' && str[i]<='9')
           {
               num[str[i]-'0']++;
                ++number;
           }
       }
       minn = 999999999;
       if(number == 10)
         minn = 247;

       else
         dfs(0,number);

       printf("%d\n",minn);
   }
   return 0;
}
void dfs(int step,int len)
{
    if(step == len)
    {
        if(len == 2)
        {
             minn = arr[0]-arr[1];
             if(minn < 0)
                minn = -1*minn;
             return ;
        }
        if(arr[len/2] == 0)
            return ;
        ll sum1 = 0 , sum2 = 0 ,i;
        for(i=0; i<len/2; i++)
            sum1 = sum1*10 + arr[i];
        for(i=len/2; i<len; i++)
            sum2 = sum2*10 + arr[i];
        int ans;
        if(sum1 > sum2)
            ans = sum1 - sum2;
        else
            ans = sum2 - sum1;
        minn = minn > ans ? ans : minn;
        return ;
    }
    if(step >=1 && arr[0]== 0 || (step>len/2 && arr[len/2]==0))
        return ;
    if(step > len/2)
    {
        int i,sum1= 0, sum2= 0;
        for(i=0; i<len/2; i++)
            sum1 = sum1*10 + arr[i];

        for(i=len/2; i<step; i++)
            sum2 = sum2*10 + arr[i];

        for(; i<len; i++)
            sum2 *= 10;
       // cout<<"hha ; "<<sum1<<" "<<sum2<<endl;
        if(minn < abs(sum1 - sum2) && sum1 < sum2)
            return ;
    }
    for(int i=0; i<=9; i++)
    {
        if(num[i] == 1)
        {
            num[i] = 0;
            arr[step] = i;
            dfs(step+1,len);
            num[i] = 1;
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值