【华为OD机考 统一考试机试C卷】 - JS篇

1. 字符串序列判定/最后一个有效字符

javascript 复制代码
const readline = require('readline');

// 创建一个readline接口对象来读取用户的输入
const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout
});

// 读取第一个字符串S
rl.on('line', (stringS) => {
  // 读取第二个字符串L
  rl.on('line', (stringL) => {
    // 初始化两个索引,分别用于遍历S和L
    let indexS = 0;
    let indexL = 0;

    // 当S和L都没有遍历完时,继续遍历
    while (indexS < stringS.length && indexL < stringL.length) {
      // 如果S中的当前字符与L中的当前字符相同,则S的索引加1
      if (stringS.charAt(indexS) === stringL.charAt(indexL)) {
        indexS++;
      }
      // 无论字符是否相同,L的索引都加1
      indexL++;
    }

    // 如果S的所有字符都在L中找到了(即S已经遍历完了),则打印L中最后一个有效字符的位置(即L的当前索引减1)
    if (indexS === stringS.length) console.log(indexL - 1);
    // 如果S还有字符没有在L中找到,则打印-1
    else console.log(-1);

    rl.close();
  });
});

2.山脉个数(逻辑)

javascript 复制代码
function count_peaks(hill_map) {
    let count = 0; // 初始化计数器为 0
    for(let i = 0; i < hill_map.length; i++){ // 遍历数组 hill_map
        if(i === 0 && hill_map[i] > hill_map[i+1]){ // 如果当前位置在数组的开头,并且当前元素大于下一个元素
            count++; // 计数器加一
        }
        if(i === hill_map.length-1 && hill_map[i] > hill_map[i-1]){ // 如果当前位置在数组的末尾,并且当前元素大于前一个元素
            count++; // 计数器加一
        }
        if(i > 0 && i < hill_map.length-1 && hill_map[i] > hill_map[i-1] && hill_map[i] > hill_map[i+1]){ // 如果当前位置不在开头和末尾,并且当前元素大于前一个元素且大于后一个元素
            count++; // 计数器加一
        }
        
    }
    return count; // 返回计数器的值作为结果
}

3.构成指定长度的字符串的个数(去重排组合)

javascript 复制代码
// 导入所需的模块
const readline = require('readline');

// 创建一个接口来读取用户的输入
const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout
});

// 递归生成满足条件的不同字符串
function generateDistinctStrings(str, length, current, set, used) {
  // 当生成的字符串长度等于指定长度时,将其加入到集合中
  if (current.length === length) {
    set.add(current);
    return;
  }

  // 遍历字符串中的字符
  for (let i = 0; i < str.length; i++) {
    // 判断字符是否已经被使用,或者当前字符与前一个字符相同
    if (used[i] || (current.length > 0 && current.charAt(current.length - 1) === str.charAt(i))) {
      continue; // 如果字符已被使用或与前一个字符相同,则跳过当前字符
    }
    used[i] = true; // 标记当前字符为已使用
    // 递归调用生成下一个字符
    generateDistinctStrings(str, length, current + str.charAt(i), set, used);
    used[i] = false; // 取消标记当前字符的使用状态,以便下一次遍历
  }
}

// 计算满足条件的不同字符串的数量
function countDistinctStrings(str, length) {
  // 创建一个集合来存储不同的字符串
  const set = new Set();
  // 创建一个数组来标记字符串中的字符是否已经被使用
  const used = new Array(str.length).fill(false);
  // 调用generateDistinctStrings方法生成满足条件的不同字符串
  generateDistinctStrings(str, length, "", set, used);
  // 打印生成的所有不同的字符串
  // for (let string of set) {
    // console.log(string);
  // }
  // 返回不同字符串的数量
  return set.size;
}

// 读取用户输入的字符串
rl.on('line', (input) => {
  // 将输入的字符串按空格分割为两部分,分别为字符串和长度
  const parts = input.split(" ");
  const str = parts[0]; // 获取输入的字符串
  const length = parseInt(parts[1]); // 将输入的长度部分转换为整数

  // 调用countDistinctStrings方法计算满足条件的不同字符串的数量
  const count = countDistinctStrings(str, length);
  // 输出计算结果
  console.log(count);

  rl.close();
});

4.用连续自然数之和来表达整数(滑动窗口)

javascript 复制代码
const readline = require('readline');

const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout
});

// 提示用户输入目标整数
rl.on('line', (target) => {
  target = parseInt(target);  // 将输入的字符串转换为整数
  console.log(`${target}=${target}`);
  
  let expressions = [];  // 存储所有满足条件的表达式

  // 遍历所有可能的起始自然数
  for (let i = 1; i < target; i++) {
    let sum = 0;
    let expression = '';

    // 从i开始累加,直到sum大于或等于target
    for (let j = i; sum < target; j++) {
      sum += j;
      expression += `${j}+`;  // 向表达式中添加自然数和加号

      // 当累加和等于目标整数时,将表达式存储到数组中
      if (sum === target) {
        expressions.push(expression.slice(0, -1));  // 去掉表达式末尾的加号
        break;
      }
    }
  }

  // 自定义比较函数,用于按表达式中自然数的个数进行排序
  expressions.sort((a, b) => {
    let aCount = a.split('+').length;
    let bCount = b.split('+').length;
    return aCount - bCount;
  });

  // 输出所有满足条件的表达式
  expressions.forEach(expression => {
    console.log(`${target}=${expression}`);
  });

  // 输出满足条件的表达式个数
  console.log(`Result: ${expressions.length + 1}`);

  rl.close();
});

5.全量和已占用字符集、字符串统计(逻辑)

javascript 复制代码
const readline = require('readline');

const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout
});

rl.on('line', (input) => {
  // 将输入字符串按照@符号分割为全量字符集和已占用字符集
  const splitInput = input.split("@");
  const fullCharacterSet = splitInput[0]; // 全量字符集
  const occupiedCharacterSet = splitInput[1]; // 已占用字符集

  // 创建字符列表,用于存储全量字符集中的字符及其对应的数量
  const characterList = [];

  // 将全量字符集按照逗号分割为单个字符
  const fullCharacterSetSplit = fullCharacterSet.split(",");

  // 遍历全量字符集的每个字符
  for (const character of fullCharacterSetSplit) {
    // 将字符按照冒号分割为字符和数量
    const characterSplit = character.split(":");
    characterList.push(characterSplit); // 将字符和数量添加到字符列表中
  }

  // 如果已占用字符集为空,则输出全量字符集
  if (occupiedCharacterSet === "") {
    console.log(fullCharacterSet + "@");
    process.exit(0);
  }

  // 创建已占用字符集的哈希表,用于存储已占用字符及其对应的数量
  const occupiedCharacters = {};

  // 将已占用字符集按照逗号分割为单个字符
  const occupiedCharacterSetSplit = occupiedCharacterSet.split(",");

  // 遍历已占用字符集的每个字符
  for (const character of occupiedCharacterSetSplit) {
    // 将字符按照冒号分割为字符和数量
    const characterSplit = character.split(":");
    occupiedCharacters[characterSplit[0]] = parseInt(characterSplit[1]); // 将字符和数量添加到已占用字符集的哈希表中
  }

  // 遍历字符列表中的每个字符
  for (let i = 0; i < characterList.length; i++) {
    const character = characterList[i];
    // 如果已占用字符集中包含当前字符
    if (character[0] in occupiedCharacters) {
      const count = parseInt(character[1]) - occupiedCharacters[character[0]]; // 计算剩余可用数量
      if (count > 0) {
        character[1] = count.toString(); // 更新字符列表中的数量为剩余可用数量
      } else {
        characterList.splice(i, 1); // 如果剩余可用数量为0,则移除当前字符
        i--; // 由于移除了一个字符,需要将索引减1
      }
    }
  }

  // 构建输出字符串
  let result = "";
  for (const character of characterList) {
    result += character[0] + ":" + character[1] + ","; // 将每个字符及其数量添加到输出字符串中
  }
  result = result.slice(0, -1); // 删除最后一个逗号
  console.log(result); // 输出结果

  rl.close();
});

6.密码输入检测(逻辑)

javascript 复制代码
const readline = require('readline').createInterface({
  input: process.stdin,
  output: process.stdout
});

readline.on('line', input => {
  let result = '';
  let isBig = false;
  let isSmall = false;
  let isNum = false;
  let isSpec = false;

  for (let c of input) {
    if (c === '<') {
      result = result.slice(0, -1);
    } else {
      result += c;
    }
  }

  for (let c of result) {
    if (/[0-9]/.test(c)) {
      isNum = true;
    } else if (/[a-z]/.test(c)) {
      isSmall = true;
    } else if (/[A-Z]/.test(c)) {
      isBig = true;
    } else {
      isSpec = true;
    }
  }

  let flagRes = result.length >= 8 && isNum && isSmall && isBig && isSpec;

  console.log(result + "," + flagRes);

  readline.close();
});

7.查找众数及中位数(逻辑)

javascript 复制代码
const readline = require('readline');

const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout
});

rl.on('line', (input) => {
  const numbers = input.split(" ").map(num => parseInt(num));

  const countMap = new Map();
  let maxCount = 0;
  for (let number of numbers) {
    let count = countMap.get(number) || 0;
    count++;
    countMap.set(number, count);
    maxCount = Math.max(maxCount, count);
  }

  const maxCountNumbers = Array.from(countMap.entries())
    .filter(entry => entry[1] === maxCount)
    .map(entry => entry[0])
    .sort((a, b) =>b - a);

  let median;
  if (maxCountNumbers.length % 2 !== 0) {
    let index = Math.floor((maxCountNumbers.length + 1) / 2) - 1;
    median = maxCountNumbers[index];
  } else {
    let index1 = maxCountNumbers.length / 2 - 1;
    let index2 = maxCountNumbers.length / 2;
    median = Math.floor((maxCountNumbers[index1] + maxCountNumbers[index2]) / 2);
  }

  console.log(median);

  rl.close();
});

8.最长的指定瑕疵的元素子串(双指针)

javascript 复制代码
const readline = require('readline');

const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout
});
rl.on('line', (line) => {
  // 输入瑕疵度
  const flaw = parseInt(line.trim());
  // 输入字符串
  rl.on('line', (line) => {
     // 移除收尾空字符串
    const s = line.trim();
    // 定义元音字母集合
    const vowels = new Set(['a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U']);
    // 记录字符串中所有元音字母的下标
    const vowelIdxs = [];
    for (let i = 0; i < s.length; i++) {
      if (vowels.has(s.charAt(i))) {
        vowelIdxs.push(i);
      }
    }
    // 初始化双指针 
    let left = 0, right = 0 ;
    // 记录所有满足瑕疵度的元音子串的长度
    const lengths = [];
    while (right < vowelIdxs.length) {
      // 计算当前子串的瑕疵度
      const lengthDiff = vowelIdxs[right] - vowelIdxs[left] - (right - left);
      if (lengthDiff > flaw) {
        // 如果瑕疵度超过了预期,左指针右移
        left++;
      } else {
        // 如果瑕疵度不超过预期,记录子串长度
        if (lengthDiff === flaw) {
          lengths.push(vowelIdxs[right] - vowelIdxs[left] + 1);
        }
        // 右指针右移
        right++;
      }
    }
    // 如果没有满足瑕疵度的元音子串,输出 0
    if (lengths.length === 0) {
      console.log(0);
      return;
    }
    // 输出最长的元音子串的长度
    lengths.sort((a, b) => b - a);
    console.log(lengths[0]);
  });
});

9.整数最小和(逻辑)

javascript 复制代码
/*
 * @Author: liwen liwen01@raxtone.com
 * @Date: 2024-04-02 14:19:20
 * @LastEditors: liwen liwen01@raxtone.com
 * @LastEditTime: 2024-04-02 14:21:13
 * @FilePath: \raxtone\Javasctipt\zhengshuzuixiaohe.js
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
const readline = require('readline');

// 创建readline接口实例
const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout
});

 rl.on('line', (array1Input) => {
  // 将输入的字符串按空格分割为数组,并将每个元素转换为数字,然后去除第一个元素
  const array1 = array1Input.split(' ').map(Number).slice(1);
   rl.on('line', (array2Input) => {
    // 将输入的字符串按空格分割为数组,并将每个元素转换为数字,然后去除第一个元素
    const array2 = array2Input.split(' ').map(Number).slice(1);

     rl.on('line', (kInput) => {
      // 将输入的字符串转换为整数
      const k = parseInt(kInput);

      // 创建一个空数组pairsSum
      const pairsSum = [];

      // 嵌套循环,将array1和array2中的元素两两相加,并将结果存储到pairsSum中
      for (const value1 of array1) {
        for (const value2 of array2) {
          pairsSum.push(value1 + value2);
        }
      }

      // 对pairsSum中的元素进行排序
      pairsSum.sort();

      // 取出pairsSum中前k个元素,并使用reduce方法计算它们的和
      const minSum = pairsSum.slice(0, k).reduce((sum, value) => sum + value, 0);

      // 输出最小和
      console.log(minSum);

      // 关闭readline接口,结束程序的执行
      rl.close();
    });
  });
});

10.找出作弊的人(排序比较)

javascript 复制代码
const readline = require('readline');

const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout
});

let input = [];

rl.on('line', (line) => {
    input.push(line.trim());
}).on('close', () => {
    // 读取员工的数量
    const n = parseInt(input.shift());
    // 创建一个数组用于存储员工的ID和分数
    const employees = input.map(line => line.split(' ').map(Number));

    // 按分数排序
    employees.sort((a, b) => a[1] - b[1]);

    let minDiff = Number.MAX_SAFE_INTEGER;
    const pairs = [];

    for (let i = 0; i < n - 1; i++) {
        for (let j = i + 1; j < n; j++) {
            const curDiff = employees[j][1] - employees[i][1];
            if (curDiff < minDiff) {
                pairs.length = 0; // 清空数组
                minDiff = curDiff;
                pairs.push({ id1: Math.min(employees[i][0], employees[j][0]), id2: Math.max(employees[i][0], employees[j][0]) });
            } else if (curDiff === minDiff) {
                pairs.push({ id1: Math.min(employees[i][0], employees[j][0]), id2: Math.max(employees[i][0], employees[j][0]) });
            } else {
                break;
            }
        }
    }

    // 对ID对进行排序
    pairs.sort((a, b) => a.id1 - b.id1 || a.id2 - b.id2);

    // 输出结果
    pairs.forEach(pair => {
        console.log(`${pair.id1} ${pair.id2}`);
    });
});

 

11.找朋友(栈)

javascript 复制代码
const readline = require('readline');
const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout
});

let n = 0;
let height = [];

rl.on('line', (input) => {
  if (!n) {
    n = parseInt(input.trim());
  } else {
    height = input.trim().split(' ').map(Number);
    
    let friendIndexes = new Array(n).fill(0);
    let stack = [0];
    for (let i = 1; i < n; i++) {
        while (stack.length && height[i] > height[stack[stack.length - 1]]) {
            friendIndexes[stack.pop()] = i;
        }
        stack.push(i);
    }
    
    let result = "";
    for (let i = 0; i < n; i++) {
        result += friendIndexes[i] + " ";
    }
    console.log(result.trim());
  }
});

12.爱吃蟠桃的孙悟空(二分法)

javascript 复制代码
// 读取标准输入
const readline = require('readline');
const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout
});

// 判断以速度k是否能在h小时内吃完所有桃子
function canFinish(p, h, k) {
    let ans = 0;
    for (let x of p) {
        ans += Math.ceil(x / k);
    }
    return ans <= h;
}

// 处理输入
rl.on('line', (input) => {
    if (!this.peachCounts) {
        // 第一行输入,转换为桃子数量数组
        this.peachCounts = input.split(' ').map(Number);
        return;
    }
    // 第二行输入,转换为小时数
    const h = Number(input);
    rl.close(); // 不再读取输入

    // 输入验证
    const n = this.peachCounts.length;
    if (n === 0 || h <= 0 || n >= 10000 || h >= 10000 || n > h) {
        console.log(0);
        return;
    }

    // 二分查找最小吃桃速度
    let left = 1, right = 1e9;
    while (left < right) {
        const mid = Math.floor((left + right) / 2);
        if (canFinish(this.peachCounts, h, mid)) {
            right = mid;
        } else {
            left = mid + 1;
        }
    }

    // 输出最小吃桃速度
    console.log(left);
});

13.游戏分组-王者荣耀(DFS)

javascript 复制代码
const readline = require('readline');

const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout
});

let res = Number.MAX_SAFE_INTEGER;
let totalSum = 0;
let targetSum = 0;


// 深度优先搜索函数
function dfs(nums, idx, count, currentSum) {
    // 剪枝条件:如果当前总和超过目标,则停止 考友反馈,去掉可得100%
    // if (currentSum > targetSum) return;

    // 当我们为一个队伍选择了5名玩家时
    if (count === 5) {
        // 计算另一个队伍的总和
        let otherTeamSum = totalSum - currentSum;
        // 用较小的差值更新结果
        res = Math.min(res, Math.abs(currentSum - otherTeamSum));
        return;
    }

    // 如果我们已经考虑了所有玩家,停止递归
    if (idx === 10) return;

    // 为第一个队伍选择当前玩家
    dfs(nums, idx + 1, count + 1, currentSum + nums[idx]);
    
    // 不为第一个队伍选择当前玩家
    dfs(nums, idx + 1, count, currentSum);
}

rl.on('line', (input) => {
    let nums = input.split(' ').map(Number);
    for (let num of nums) {
        totalSum += num;
    }
    targetSum = totalSum / 2;
    dfs(nums, 0, 0, 0);
    console.log(res);
    rl.close();
});

14.求满足条件的最长子串的长度(滑动窗口)

javascript 复制代码
const readline = require('readline').createInterface({
  input: process.stdin,
  output: process.stdout
});

// 读取输入的字符串
readline.on('line', (str) => {
  // 初始化最长子串长度为-1
  let maxLen = -1;
  // 初始化一个标志,表示是否找到了包含字母的子串
  let hasLetter = false;

  // 初始化双指针l和r,分别表示子串的左右边界
  let l = 0, r = 0;
  // 创建一个双端队列用于存储字母的索引
  let letterIdx = [];

  // 遍历字符串
  while (r < str.length) {
    // 获取当前字符
    let c = str.charAt(r);

    // 如果当前字符是字母
    if (c.match(/[a-zA-Z]/)) {
      // 设置标志为true,表示找到了包含字母的子串
      hasLetter = true;
      // 将字母的索引添加到队列的尾部
      letterIdx.push(r);

      // 如果队列中有多于1个字母的索引
      if (letterIdx.length > 1) {
        // 移除队列头部的字母索引,并将左指针l移动到该索引的下一个位置
        l = letterIdx.shift() + 1;
      }

      // 如果右指针r等于左指针l,跳过当前循环
      if (r === l) {
        r++;
        continue;
      }
    }

    // 更新最长子串长度
    maxLen = Math.max(maxLen, r - l + 1);
    // 移动右指针
    r++;
  }

  // 如果没有找到包含字母的子串,输出-1
  if (!hasLetter) {
    console.log(-1);
  } else {
    // 否则输出最长子串长度
    console.log(maxLen);
  }

  readline.close();
});

15. 分割均衡字符串(贪心)

javascript 复制代码
const readline = require('readline');

const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout
});

rl.on('line', (s) => {
  // 初始化变量,用于记录可分割成新的均衡子串的最大个数
  let ans = 0;
  // 初始化变量,用于记录当前位置字符'X'和'Y'的差值
  let count = 0;

  // 遍历字符串的每个字符
  for (let i = 0; i < s.length; i++) {
    // 判断当前字符是'X'还是'Y'
    if (s.charAt(i) === 'X') {
      // 如果是'X',则将count加1,表示出现了一个'X'
      count++;
    } else {
      // 如果是'Y',则将count减1,表示出现了一个'Y'
      count--;
    }

    // 在每次更新count后,判断count是否为0
    if (count === 0) {
      // 如果为0,表示当前位置可以作为分割点,将ans加1
      ans++;
    }
  }

  // 输出可分割成新的均衡子串的最大个数
  console.log(ans);

  rl.close();
});

16.机器人仓库搬砖(二分法)

javascript 复制代码
function minEnergyBlocks(bricks, hours) {
    if (bricks.length > 8) { // 如果砖块数量大于8
        return -1; // 返回-1
    }
    let left = 1, right = Math.max(...bricks); // 初始化左右边界
    while (left < right) { // 二分查找
        let middle = Math.floor((left + right) / 2); // 取中间值
        let total_time = 0; // 计算当前能量块数量下能够搬完所有砖的总时间
        for (let i = 0; i < bricks.length; i++) {
            total_time += Math.ceil(bricks[i] / middle);
        }
        if (total_time > hours) { // 如果当前能量块数量下搬完所有砖的总时间超过了限定时间,缩小搜索范围
            left = middle + 1;
        } else { // 否则,减小能量块数量
            right = middle;
        }
    }
    let sum = 0;
    for (let i = 0; i < bricks.length; i++) {
        sum += Math.ceil(bricks[i] / left);
    }
    if (sum > hours) { // 检查最终确定的能量块数量是否能在规定时间内搬完所有砖
        return -1; // 无法在规定时间内搬完所有砖
    }
    return left; // 返回最小能量块数量
}

const readline = require('readline');
const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout
});

rl.on('line', (input) => {
    const bricks = input.split(' ').map(Number);
    console.log(minEnergyBlocks(bricks, 8)); // 调用函数并输出结果
    rl.close();
});

17.出租车计费 、靠谱的车(逻辑)

javascript 复制代码
const readline = require('readline');

const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout
});

rl.on('line', (line) => {
  let correct = 0;
  for (let i = 0; i < line.length; i++) {
    let digit = parseInt(line[i]);
    if (digit > 4) {
      digit--;
    }
    correct = correct * 9 + digit;
  }
  console.log(correct);
});

18.开源项目热度榜单

javascript 复制代码
/*
 * @Author: liwen liwen01@raxtone.com
 * @Date: 2024-04-02 19:59:07
 * @LastEditors: liwen liwen01@raxtone.com
 * @LastEditTime: 2024-04-02 20:00:15
 * @FilePath: \raxtone\Javasctipt\openproject.js
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
const readline = require('readline');

const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout
});

// 创建一个数组用于存储用户的输入
let input = [];
// 当接收到一行输入时,将其去除首尾空格后添加到input数组中
rl.on('line', (line) => {
    input.push(line.trim());
}).on('close', () => { // 当输入结束时,执行以下代码
    // 读取项目数量n
    const n = parseInt(input[0]);
    // 读取权重数组,将其转换为数字数组
    const weights = input[1].split(' ').map(Number);

    // 创建一个数组用于存储项目信息
    let projects = [];
    // 读取每个项目的信息
    for (let i = 2; i < 2 + n; i++) {
        // 将项目信息分割为名称和评分数组
        const project = input[i].split(' ');
        const name = project[0];
        const scores = project.slice(1).map(Number);

        // 计算项目的热度
        let hotness = 0;
        for (let j = 0; j < 5; j++) {
            hotness += scores[j] * weights[j];
        }

        // 将项目的名称和热度添加到projects数组中
        projects.push({ name, hotness });
    }

    // 对项目数组进行排序,首先根据热度降序排序,如果热度相同则根据名称升序排序
    projects.sort((a, b) => {
        if (a.hotness !== b.hotness) {
            return b.hotness - a.hotness;
        } else {
            return a.name.localeCompare(b.name);
        }
    });

    // 遍历排序后的项目数组并打印项目名称
    for (let project of projects) {
        console.log(project.name);
    }
});

19.寻找身高相近的小朋友

javascript 复制代码
const readline = require('readline');

// 创建readline接口,用于读取输入
const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout
});

let h, n;
let heights = [];

// 监听输入事件
rl.on('line', (input) => {
  // 如果h和n未赋值,表示当前输入为第一行,包含小明的身高和新班级其他小朋友的个数
  if (!h && !n) {
    const inputArr = input.split(' ');
    h = parseInt(inputArr[0]);
    n = parseInt(inputArr[1]);
  } else {
    // 否则,表示当前输入为第二行,包含其他小朋友的身高
    const heightArr = input.split(' ');
    // 将输入的身高字符串转换为整数并存储在heights数组中
    heights = heightArr.map(height => parseInt(height));
    // 对heights数组进行排序
    heights.sort((a, b) => {
      const diffA = Math.abs(a - h);
      const diffB = Math.abs(b - h);
      // 如果两个小朋友和小明身高差一样,则个子较小的小朋友排在前面
      if (diffA === diffB) {
        return a - b;
      }
      // 否则,根据与小明身高差的绝对值进行排序
      return diffA - diffB;
    });
    // 输出排序后的结果
    console.log(heights.join(' '));
  }
});

20.考勤信息(逻辑)

javascript 复制代码
// 引入readline模块用于读取命令行输入
const readline = require('readline');

// 创建readline接口实例
const rl = readline.createInterface({
    input: process.stdin, // 标准输入流
    output: process.stdout // 标准输出流
});

// 定义函数判断是否能获得考勤奖
const canReceiveAward = (records) => {
    let absentCount = 0; // 缺勤次数计数器
    for (let i = 0; i < records.length; i++) {
        if (records[i] === 'absent') { // 如果记录为缺勤
            absentCount++; // 缺勤次数加1
            if (absentCount > 1) return false; // 缺勤超过1次,返回false
        }
        if (records[i] === 'late' || records[i] === 'leaveearly') { // 如果记录为迟到或早退
            // 如果前一天也是迟到或早退,返回false
            if (i > 0 && (records[i - 1] === 'late' || records[i - 1] === 'leaveearly')) {
                return false;
            }
        }
        if (i >= 6) { // 检查任意连续7天的考勤记录
            let countIn7Days = 0; // 连续7天内非正常上班的天数
            for (let j = i - 6; j <= i; j++) {
                if (records[j] !== 'present') { // 如果这7天内有非出勤记录
                    countIn7Days++;
                }
            }
            if (countIn7Days > 3) return false; // 如果连续7天内非正常上班超过3天,返回false
        }
    }
    return true; // 所有条件都满足,返回true
};

let lines = []; // 存储输入行的数组

// 监听命令行输入
rl.on('line', (line) => {
    lines.push(line); // 将每行输入存储到lines数组中
}).on('close', () => { // 输入结束时触发
    const testCases = parseInt(lines[0], 10); // 解析测试用例数量
    for (let i = 1; i <= testCases; i++) { // 遍历每个测试用例
        const attendanceRecords = lines[i].trim().split(" "); // 分割考勤记录
        // 输出每个测试用例的结果,并根据条件添加空格分隔
        process.stdout.write(canReceiveAward(attendanceRecords) ? "true" : "false");
        if (i < testCases) {
            process.stdout.write(" ");
        }
    }
    process.exit(0); // 执行完毕后退出程序
});
相关推荐
legend_jz1 分钟前
【Linux】线程控制
linux·服务器·开发语言·c++·笔记·学习·学习方法
小镇程序员14 分钟前
vue2 src_Todolist全局总线事件版本
前端·javascript·vue.js
野槐16 分钟前
前端图像处理(一)
前端
tangliang_cn22 分钟前
java入门 自定义springboot starter
java·开发语言·spring boot
程序猿阿伟23 分钟前
《智能指针频繁创建销毁:程序性能的“隐形杀手”》
java·开发语言·前端
疯狂的沙粒25 分钟前
对 TypeScript 中函数如何更好的理解及使用?与 JavaScript 函数有哪些区别?
前端·javascript·typescript
瑞雨溪33 分钟前
AJAX的基本使用
前端·javascript·ajax
新知图书34 分钟前
Rust编程与项目实战-模块std::thread(之一)
开发语言·后端·rust
威威猫的栗子36 分钟前
Python Turtle召唤童年:喜羊羊与灰太狼之懒羊羊绘画
开发语言·python
力透键背36 分钟前
display: none和visibility: hidden的区别
开发语言·前端·javascript