前言
本来排名是20的,不过第一题有点输出bug,最后实际测出来又重新排名,刚好卡在第10。但是考试报告好像过了12小时就下载不到了,所以就只写题目求解的JS函数吧。
1. 幸运数字
小艺定义一个幸运数字的标准包含3条:
- 仅包含4或7
- 幸运数字的前半部分数字之和等于后半部分数字之和
- 数字长度是偶数
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)
X−X/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;
}