1010

#include <stdio.h>
#include<algorithm>
int values[26];//记录值
int value_repeat[26];//记录值重复的情况
int number;//值的个数
int uses[4];//使用到的值
int use_number;//使用到的值的个数
#define MIN(a,b) (a<b?a:b)
typedef struct SResult{
    int cards[4];//使用到的记录
    int use_number;//尽可能少
    int type_number;//尽可能多
    int max_value;//尽可能大
    int n;//出现的次数
}SResult;
SResult best_result;
int fFind(int i_index,int need_value)
{
    if(need_value ==0)
    {//成功了
        //只有在结果不比最优结果差的时候才会影响最优解
        int type_number = 0;
        int use_card = use_number;
        int max_value = uses[0];
        int i,j,n=1;
        for(i = 0,j=1;i < use_number-1;++i)
        {
            if(uses[i] == uses[i+1])
            {
                ++j;
            }else
            {
                int i_repeat = value_repeat[uses[i-j+1]];
                type_number += MIN(j,i_repeat);
                if(i_repeat > j
                ||(i_repeat < j
                   && i_repeat!=1))
                {
                    n = 2;
                }
                j =1;
            }
        }
 
        if(use_number != 1 &&
                uses[use_number -1]==uses[use_number-2])
        {//倒数两个是重复的,在上面的循环中是无法计算到的
            int i_repeat = value_repeat[uses[i-j+1]];
            type_number += MIN(j,i_repeat);
            if(i_repeat > j
            ||(i_repeat < j
               && i_repeat!=1))
            {
                n = 2;
            }
        }else
        {//为use_number == 1 与最后两个不相同的情况加1
            type_number += 1;
        }
 
        if(best_result.n == 0
                ||type_number>best_result.type_number
                ||(type_number==best_result.type_number
                   &&
                   (use_card < best_result.use_number
                    ||(use_card == best_result.use_number
                       &&max_value > best_result.max_value
                       )
                    )
                   )
                )
        {//获取到更优的解了
            best_result.n = n;
            best_result.max_value = max_value;
            best_result.type_number = type_number;
            best_result.use_number = use_card;
            for(i =0;i<use_card;++i)
            {
                best_result.cards[i] = uses[i];
            }
        }else if(type_number==best_result.type_number
                 &&use_card == best_result.use_number
                 &&max_value == best_result.max_value)
        {//获取到重复的最优解了
            best_result.n = 2;
        }
        if(best_result.type_number == MIN(4,number)
                &&(best_result.n > 1
                   ||(best_result.n == 1
                      &&max_value < best_result.max_value)))
        {//不可能有更好的结果了
            return 1;//表示已经有结果了
        }
        return 0;
    }
    int value = values[i_index];
    if(value*(4-use_number)<need_value)
    {//已经不可能了
        return 0;
    }
 
    //使用这个值
    if(value <= need_value)
    {
        uses[use_number++] = i_index;
        if(fFind(i_index,need_value - values[i_index]))
        {
            return 1;
        }
        --use_number;
    }
    //不使用这个值得邮票
    //找到下一个值
    i_index -= value_repeat[i_index];
    if(i_index <0)
    {//已经没有了
        return 0;
    }
    return fFind(i_index,need_value);
}
int fFindAndShow()
{
    int need_value;
    scanf("%d",&need_value);
    if(need_value == 0)
    {
        return 0;
    }
    use_number = 0;
    best_result.n = 0;
    fFind(number-1,need_value);
    if(best_result.n == 0)
    {
        printf("%d ---- none\n",need_value);
    }else if(best_result.n )
    {
        printf("%d (%d):",need_value,best_result.type_number);
        if(best_result.n == 1)
        {
            for(;best_result.use_number>0;)
            {
                printf(" %d",values[best_result.cards[--best_result.use_number]]);
            }
        }else
        {
            printf(" tie");
        }
        printf("\n");
    }
    return 1;
}
int main(void)
{
 
    while(scanf("%d",values+number++)!=EOF)
    {
        if(values[number-1] == 0)
        {//一次value输入结束了
            int i,j;
            number--;
            std::sort(values,values+number);
            //初始化重复值的情况
            for(j=1,i = number-1;i>0;--i)
            {
                if(values[i] == values[i-1])
                {
                    ++j;
                }else
                {
                    value_repeat[i+j-1] = j;
                    j = 1;
                }
            }
            value_repeat[i+j-1] = j;
            j = 1;
            value_repeat[0] = 1;
            while(fFindAndShow());
            number = 0;
        }
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值