【CSDN竞赛】27期题解(Javascript)

前言

本来排名是20的,不过第一题有点输出bug,最后实际测出来又重新排名,刚好卡在第10。但是考试报告好像过了12小时就下载不到了,所以就只写题目求解的JS函数吧。

1. 幸运数字

小艺定义一个幸运数字的标准包含3条:

  1. 仅包含4或7
  2. 幸运数字的前半部分数字之和等于后半部分数字之和
  3. 数字长度是偶数

JS技巧:在通过readLine().trim()函数读取输入后别使用模板的parseInt()转成整数,而是直接对获取的字符串进行操作。

function luckyNumber(str){
    if(str.length % 2 != 0) return false;
    // 因为前半部分和后半部分的长度相同、和也相同,故前半部分的4的个数必定等于后半部分4的个数,同理,7也相等。
    // 遇到前半部分相加,后半部分就相减,最后得到0即可。
    let count4 = 0;
    let count7 = 0;    
    for(let i=0;i<str.length/2;i++){
        if(str[i] !== '4' && str[i] !== '7'){
            return false;
        }
        if(str[i] == '4'){
            count4++;
        }else{
            count7++;
        }
    }
    for(let i=str.length/2;i<str.length;i++){
        if(str[i] !== '4' && str[i] !== '7'){
            return false;
        }
        if(str[i] == '4'){
            count4--;
        }else{
            count7--;
        }
    }
    if(count4 == 0 && count7 == 0) return true;
    return false;
}

2. 连续进球

小明投篮,罚球线投球可得1分,在三分线内投篮得分可以得到2分,在三分线以外的地方投篮得分可以得到3分,连续投进得分累计。
一旦有一个球没投进则得分清零,重新计算。
现给出所有得分记录(清零不计入得分),请你计算一下小明 最多连续投进多少个球?

说明:

  • 由于需要计算最多连续投的个数,所以转化为分数递增的最长长度即可。
  • 好像CSDN给出的数据比较友好,清零的数据不会给出。也就是说得分数组不含0。
function maxBall(scoreArr){
    if(scoreArr.length == 0) return 0
    let count = 1;
    let maxCount = 1;
    for(let i = 1;i<scoreArr.length;i++){
        if(scoreArr[i] > scoreArr[i-1]){
            count++;
            maxCount = Math.max(count,maxCount);
        }else{
            count = 1;
        }
    }
    maxCount = Math.max(count,maxCount)
    return maxCount;
}

3. 货币种类

X国发行货币最高面额为n。 次高面额为n的因子。 以此类推。 X国最多发行多少种货币。

吐槽: 给出输入n = 10 ,输出货币种类3种。
这题没说清楚,类推的规律是什么,只能根据答案反推是 货币为 10 5 1
低级的货币面额是高一级货币面额的最大因子

function moneyKinds(n){
    let result = 1;//每个数必包含因子1
    while(n!=1){
        result++; //先加上当前面额
        for(let i=2;i<=n;i++){
            if(n%i==0){
                n=n/i; //找到最大的因子
                break;
            }
        }
    }
    return result;    
}

4. 黑板擦末尾数字

小明选择了一个正整数X,然后把它写在黑板上。
然后每一天他会擦掉当前数字的最后一位,直到他擦掉所有数位。
在整个过程中,小明会把所有在黑板上出现过的数字记录下来,然后求出他们的总和sum.
例如X = 509, 在黑板上出现过的数字依次是509, 50, 5, 他们的和就是564.
小明现在给出一个sum,小明想让你求出一个正整数X经过上述过程的结果是sum.

思路,这题采用有剪枝条件的暴力模拟,穷举X,然后一遍遍模拟加上去。
先给出我们穷举X的起始值,证明:

因为每次擦除末尾数字 = X/10 (保留整数)
X + X / 10 + X / 10 / 10 + . . . = s u m X + X/10 + X/10/10 + ... = sum X+X/10+X/10/10+...=sum
等式两端再除10:
X / 10 + X / 10 / 10 + X / 10 / 10 / 10 + . . . = s u m / 10 X/10 + X/10/10 + X/10/10/10 + ... = sum/10 X/10+X/10/10+X/10/10/10+...=sum/10
两式对应相减,可以得到一个X上限值:
X − X / 10 / 10 / 10... ( 个位 ) = s u m − ( s u m / 10 ) X - X/10/10/10...(个位 ) = sum - (sum / 10) XX/10/10/10...(个位)=sum(sum/10)
也就是说X减去它的个位数 = sum - sum/10
X > s u m − ( s u m / 10 ) X > sum - ( sum / 10 ) X>sum(sum/10)
至此,我们从sum - (sum / 10) 开始枚举,不断增大假设值即可。
同时穷举次数应该不超过10次。

// 返回-1 说明找不到
function findX(sum){
    let X = sum - Math.floor(sum / 10)
    while (1){
        let x = X;
        let nowSum = x;
        while (x){
            x = Math.floor(x/10);
            nowSum += x;
        }
        if (sum == nowSum){//找到这个整数
            break;
        }
        else if (sum_result < sum){ //sum小,就增大X
            X++;
        }
        else{    //sum大,说明超出,找不到了。
            X = -1;
            break;
        }
    }
    return X;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

如果皮卡会coding

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值