CSDN周赛解析:第 27 期
- 👉 前言
- 👉 第一题: 幸运数字
- > 解析
- > 解决方案
- > 拓展知识
- 👉 第二题: 投篮
- > 解析
- > 解决方案
- 👉 第三题: 通货膨胀-x国货币
- > 解析
- > 解决方案
- 👉 第四题: 最后一位
- > 解析
- > 解决方案
- 往期内容 💨
👉 前言
各位卷王们好! 基于最近比较经常接触算法相关的编程题,所以于前天,也就是CSDN第27期周赛。报名参加了,为了记录一下自己在哪里跌倒,特此打算新开一个栏目,名为: CSDN周赛解析
。
希望大伙不要吝啬,三连支持一下呀!
👉 第一题: 幸运数字
小艺定义一个幸运数字的标准包含3条:
- 仅包含4或7。
- 幸运数字的前半部分数字之和等于后半部分数字之和。
- 数字的长度是偶数。
> 解析
根据题目可以得出,幸运数字有三条规则判定,本题较为简单,配合解决方案更好理解!
> 解决方案
具体解析均有注释,方便日后查漏补缺!
class Solution {
solution(n) {
// 通过将数字转换成数值数组,方便利用数组自带的函数
var arr = String(n).split('').map(item => Number(item))
// TODO: 请在此编写代码
/*
判断1:通过取余的方式,判断是否为偶数
判断2:通过数组函数filter会返回符合逻辑语句的数组,判断前后的长度是否相同来判断,是否符合幸运数字均为4 或 7 的判断
*/
if(arr.length%2 != 0 || arr.filter(item => (item == 4 || item == 7)).length !== arr.length) {
return 'No'
}
/*
通过数组函数slice(indexStrat, indexEnd), 截出一个新的数组(需要注意,slice()和splice()的区别),将幸运数字分割成前后两部分,进行累加对比
*/
if(arr.slice(0,(arr.length/2)).reduce((prev, curr) => prev + curr) != arr.slice(arr.length/2, arr.length).reduce((prev, curr) => prev + curr)) {
return 'No'
}
return 'YES'
}
}
var str_0 = readline().trim();
var n = parseInt(str_0);
let sol = new Solution();
result = sol.solution(n);
print(result);
在比赛时,这道题是存在bug的,bug是返回Yes时字母是全部大写的,而No只有首字母是大写的。当时不够细心,没测出来,以为是编码问题。可惜了,只拿到6分。
> 拓展知识
在使用slice()
和 splice()
时,需要注意二者的区别,虽然它们都是对于数组对象进行截取,但是二者还是存在明显区别。具体如下:
- 函数参数上
slice
和splice
第一个参数都是截取开始位置,slice
第二个参数是截取的结束位置(不包含), 而splice
第二个参数(表示这个从开始位置截取的长度)。 slice
不会对原数组产生变化, 而splice
会直接剔除原数组中的截取数据 !splice
更多被用于对原数组的增删改
👉 Array.prototype.splice() 详细
👉 Array.prototype.slice() 详细
👉 < Javascript中数据处理小技巧 — 数组篇 >
👉 第二题: 投篮
小明投篮,罚球线投球可得1分,在三分线内投篮得分可以得到2分,在三分线以外的地方投篮得分可以得到3分,连续投进得分累计,一旦有一个球没投进则得分清零,重新计算。
现给出所有得分记录(清零不计入得分),请你计算一下小明最多连续投进多少个球?
> 解析
根据题目可以得出,投篮得分总共有三种得分方式,分别是: 罚球线 + 1、三分线内 + 2、三分线外 + 3。
那么我们可以通过让当前分数,分别 + 1,+2, +3后,和下一个得分总和相比。如果相等,证明是成功进球了的。
> 解决方案
具体解析均有注释,方便日后查漏补缺!
class Solution {
solution(n, arr) {
/*
result 用于记录最多连续进球数
curr 用于记录当前最多连续进球数
因为是记录得分了,只要记录得分的arr数组长度不等于0,初始值就为1。
*/
const INITVAL = arr.length !== 0 ? 1 : 0
var result = INITVAL
var curr = INITVAL
// 循环投球次数,将得分数组按照进球得分的三种分类,逐个比对。
// 只要有一个相等则为进球,否则重置当前连续进球数
for(let times = 0; times < n; times++ ) {
// 比较当前连续进球数和全局最高连续进球数
result = Math.max(result, curr)
if(arr[times]+1 == arr[times+1] || arr[times]+2 == arr[times+1] || arr[times]+3 == arr[times+1])
{
curr++
} else {
curr = INITVAL
}
}
// TODO: 请在此编写代码
return result;
}
}
var str_0 = readline().trim();
var n = parseInt(str_0);
var str_1 = readline();
var line_list_1 = str_1.trim().split(" ");
var arr = new Array();
for(var i = 0; i < line_list_1.length; i++){
arr[i] = parseInt(line_list_1[i]);
}
let sol = new Solution();
result = sol.solution(n, arr);
print(result);
👉 第三题: 通货膨胀-x国货币
X国发行货币最高面额为n。 次高面额为n的因子。
以此类推,X国最多发行多少种货币。
> 解析
根据题目可以得出,这题是考我们对因子概念。
在数学中,如果整数A除B,得出结果是没有余数的整数,就称B是A的因子。
比如8的因子有1,2,4和8。
根据题目分析,说是次高面额为n的因子,然后以此类推。 那么这里的n是会变化的,在取到因子后,需要更新n为当前面额数为n。例子如下:
最高面额为10的货币,第一个因子为5, 而5的因子,只有1和它本身,但货币种类不能重复,故只有三种,分别为 10块,5块,1块。
> 解决方案
具体解析均有注释,方便日后查漏补缺!
class Solution {
solution(n) {
var result = 0;
// 定义当前的最高面额值为n
let curr = n
for(let num = n; num >= 1; num--) {
// 通过取余的方法判断是否为因子
if(curr%num == 0) {
curr = num
result++
}
}
// TODO: 请在此编写代码
return result;
}
}
var str_0 = readline().trim();
var n = parseInt(str_0);
let sol = new Solution();
result = sol.solution(n);
print(result);
👉 第四题: 最后一位
小明选择了一个正整数X,然后把它写在黑板上。然后每一天他会擦掉当前数字的最后一位,直到他擦掉所有数位。
在整个过程中,小明会把所有在黑板上出现过的数字记录下来,然后求出他们的总和sum。
例如X = 509, 在黑板上出现过的数字依次是509, 50, 5, 他们的和就是564.
小明现在给出一个sum,小明想让你求出一个正整数X经过上述过程的结果sum.
> 解析
根据题目可以得出,最后的和,是根据逐位擦除的数相加,那么这个数必然小于sum。由此,我们可以通过循环这个sum值,将值根据逐位除于10相加,判断是否等于sum,以此来判断是否符合条件。
> 解决方案
具体解析均有注释,方便日后查漏补缺!
class Solution {
solution(X) {
var result = 0;
// TODO: 请在此编写代码
while (X > 0) {
result += X;
X /= 10;
}
return result;
}
}
var str_0 = readline().trim();
var sum = parseInt(str_0);
let sol = new Solution();
result = sol.solution(sum);
print(result);
不难看出,一个数的sum一定比这个数本身大,所以结果就在0到sum之间。
测试数据比较水,直接使用暴力模拟法,即可通过此题。
往期内容 💨
🔥 < 每日算法 - JavaScript解析:二叉树灯饰【初识动态规划 - dp, 具体理解配合代码看最合适,代码均有注释】 >
🔥 < 每日算法 - Javascript解析:经典弹珠游戏 >
🔥 < 每日算法 - JavaScript解析:从尾到头打印链表 >
🔥 < JavaScript技术分享: 大文件切片上传 及 断点续传思路 >