蓝桥杯:颠倒的价牌

目录

题目描述

题目分析:

        暴力枚举+列表+字符替换

AC代码(Java):

答案:

PS:按照题意,其实是有两个答案的

 当亏损的原价是7089时:

当亏损原价是9088时:


题目描述

本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。

题目分析:

        暴力枚举+列表+字符替换

         (1):因为满足亏损和盈利条件的有很多,所以我们使用两个列表来记录(方便动态扩容)。

         (2):然后找出他们相差小的那个(题目要求价格出入不大)。

         (3):同时要明白,价格放反了,不单单是反转那么简单,需要对6 or 9这两个特殊数字进行特殊处理(6变9)(9变6)。

         (4):还有赔钱和赚钱的区分。

         赔钱是因为,原价>放反了的原价,这时候才会出现亏损。

         赚钱是因为,原价<放反了的原价,所以才会比原价多赚钱。

         (5):至于1110 就不能倒过来,因为 0 不能作为开始数字。我在遍历所有可行性的时候没有发现出现这种数据的情况,就无视了。

AC代码(Java):

import java.util.*;
// 1:无需package
// 2: 类名必须Main, 不可修改

public class Main {
    public static void main(String[] args) {
        /**
         * 因为满足亏损和盈利条件的有很多,所以我们使用两个列表来记录(方便动态扩容)。
         * 然后找出他们相差小的那个(题目要求价格出入不大)。
         * 同时要明白,价格放反了,不单单是反转那么简单,需要对6 or 9这两个特殊数字进行特殊处理(6变9)(9变6)
         * 还有赔钱和赚钱的区分。
         * 赔钱是因为,原价>放反了的原价,这时候才会出现亏损。
         * 赚钱是因为,原价<放反了的原价,所以才会比原价多赚钱。
         * 至于1110 就不能倒过来,因为 0 不能作为开始数字。我在遍历所有可行性的时候没有发现出现这种数据的情况,就无视了
         * 别问为什么特别注释这个。我5分钟出答案(踩坑了),Debug找了半小时
         * */
        List<Integer> A = new ArrayList<>();    //记录亏损
        List<Integer> B = new ArrayList<>();    //记录盈利
        for(int i = 1000;i<10000;i++){
            //先拿到亏损
            int loss = reverse(i);
            //确定亏损范围,因为原价是比反转之后高的,所以他们的差价是[200,300)这个区间,是个整数
            if(loss<=200 || loss>300){
                continue;
            }
            //确定亏损之后,再找盈利的
            //因为反转会修改数字,所以也不好确定从哪里开始盈利,直接全部遍历
            for(int j = 1000;j<10000;j++){
                int profit = reverse(j);
                //确定盈利的区间,是[-800,-900) 这个之间
                //因为将价格反转之后,还赚了[800,900)这个区间,那么代表原价卖肯定得不到这个钱,只有反转之后的价格比原价高才行
                //但是我们的reverse()方法是返回原价-反转之后的价格的,所以得到的肯定是负数
                if(profit<=-800 && profit>-900){
                    //确定了盈利之后,判断亏损+558 是否等于赚钱(绝对值)
                    if(Math.abs(profit) == loss+558){
                        //盈利和亏损相差558,就将他们两个的原价记录到列表里面
                        A.add(i);
                        B.add(j);
                    }
                }
            }
        }
        System.out.println(min(A,B));
    }
    /** 处理反转
     * @return:返回他们的差值,即i和i的反转
     * **/
    public static int reverse(int num){
        //先对num进行反转
        StringBuffer sb = new StringBuffer(num + "");
        sb.reverse();
        //反转之后如果有9or6需要对他们进行修改
        String str = check(sb.toString());
        //修改之后返回他们的差值
        return num-Integer.valueOf(str);
    }
    /** 检查需要反转之后的数字,9变成6,6变成9
     * @return : 返回修改后的字符串
     * **/
    public static String check(String str){
        char[] ch = str.toCharArray();
        for(int i = 0;i<ch.length;i++){
            if(ch[i] == '9'){
                ch[i] = '6';
            }else if(ch[i] == '6'){
                ch[i] = '9';
            }
        }
        return String.valueOf(ch);
    }
    /**处理两个列表中相差较小的原价
     * @return:返回两个列表中相差较小的原价(亏损的原价)
     * */
    public static int min(List<Integer> A,List<Integer> B){
        //记录他们的相差,每次得到新的小的差价,就更新min和下标index
        int min = Integer.MAX_VALUE;
        int index = 0;
        //因为A和B的长度肯定是相同的(同时添加),直接每次取出第一个就行
        while(!A.isEmpty()){
            //同时取出A和B的第一个
            int a = A.remove(0);
            int b = B.remove(0);
            //比较
            if(Math.abs(a-b)<=min){
                //这里的判断为什么是<=min呢?
                /**
                 *  因为存在两个价格,他们相差都是22,他们的亏损和盈利相差也都是558
                 *  一个是7089和7067
                 *  一个是9088和9066
                 *  但是我看了半天题目,都没有说为什么9088可以,7089不行
                 * **/
                min =  Math.min(min,Math.abs(a-b));
                index = a;
            }
        }
        return index;
    }
}

答案:

        

PS:按照题意,其实是有两个答案的

         和

 当亏损的原价是7089时:

        它的价格反过来,是6807,也就是亏损282元。赚钱的原价是7067,反过来是7907,赚钱840元,那么 赚钱-亏损是刚好等于 558的。而且他们相差也是只有22.

当亏损原价是9088时:

        它的价格反过来,是8806,亏损282元。赚钱的原价是9066,反过来是9906,赚钱840元,那么赚钱-亏损也是等于558,他们相差也是22.

        那么为什么?

 我不理解,但我大受震撼。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值