Sicily 1239.Smallest Differencev

 

注:思路分析来源于ID为jasison的博主http://blog.csdn.net/jasison/article/details/8477279,代码也是模仿而写,稍有优化。(请支持正版原创)

题意:

给定n(2 <= n <= 10)个不重复的十进制数字('0'-'9'),让这n个数字不重复使用地构成两个数,使这两个数的差的绝对值最小。

比如,0 1 2 4 6 7,构成176 和 204 能使差最小为28。

思路:

贪心。分情况讨论。

1)是有奇数个数的话,那么,选择非零的最小的数字作为较大数的最高位,最后一位数字作为较小数的最高位,然后较大数从后往前取次位,较小数从前往后取次位。

如0 1 2 4 5 7 8,较大数的最高位就是1(次高位可以直接判断出来是0),较小数的次高位就是8,然后依次取,得到(10,8),(102,87),(1024,875),就能得到答案。

2)是有2个数的话,那么直接两个数相减就能得到答案。

3)非2个的偶数个数,这是比较麻烦的一种情况,首先必须使最高位的差最小,就可以遍历一遍找到最高位的差的最小值。然后再遍历一遍,对每一对最高位的差为最小值的两个数进行枚举,较小数的最高位为较小的那个数,较大数的最高位为较大的那个数,较大数的次位从前往后取,较小数的次位从后往前取。

如1 3 5 7,最高位的差为2,枚举所有的最高位的差为2 的数对(1,3),(3,5),(5,7)。然后取次位,分别得到(1,3)-> (17,35)= 18,(3,5)-> (37,51)= 14,(5,7)-> (53,71)= 18,比较得到答案为14。

#include <iostream>
#include<cstdio>
using namespace std;

struct Temp
{
       int x;
       int y;
};
int main()
{
    int T;
    cin>>T;
     getchar();
    while(T--)
    {
     
             
              int a[11],n=0,ans,num1,num2;
              char c;
              
              while(cin.get(c))
              {
                if(c=='\n')
                           break;
                else if(c!=' ')
                a[n++]=c-'0';
              }
              if(n==2) ans=a[1]-a[0];
              else
              {
                  if(n%2!=0)
                  {
                          num1= a[0]==0? a[1]*10:a[0]*10+a[1];
                          num2= a[n-1];
                          for(int i=0;i<(n-3)/2;++i)
                          {
                                  num1=10*num1+a[i+2];
                                  num2=10*num2+a[n-i-2];
                          }
                          ans = num1-num2;
                  }
                  else
                  {
                      int dif=11,count=0;
                      for(int i= a[0]==0? 1:0 ;i<n-1;i++)
                      {
                              if(a[i+1]-a[i]<dif)
                                 dif=a[i+1]-a[i];
                      }
                      Temp temp[11];
                      for(int i= a[0]==0? 1:0 ;i<n-1;i++)
                      {
                          if(a[i+1]-a[i]==dif)
                          {
                            temp[count].x=a[i];
                            temp[count].y=a[i+1];
                            count++;
                          }
                      }
                      ans=1000000000;
                      for(int i=0;i<count;i++)
                      {
                         int h=1; 
                         num2=temp[i].y;
                         for(int j=0;h<=n/2-1;j++)
                         { 
                             if(a[j]!=temp[i].x&&a[j]!=temp[i].y)
                             {
                                num2=num2*10+a[j];
                                 h++;
                             }
                             else 
                                  continue;
                         }
                         h=1; 
                         num1=temp[i].x;
                         for(int j=n-1;h<=n/2-1;j--)
                         {
                             if(a[j]!=temp[i].x&&a[j]!=temp[i].y)
                             {
                                num1=num1*10+a[j];
                                h++;
                             }
                             else 
                                  continue;
                         }
                         if(ans>num2-num1)
                             ans=num2-num1;
                      }
                  }
                         
              }
              cout<<ans<<endl;
              
    }
    return 0;
}                                 


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值