某大厂2022笔试编程题——js(v8)版本

278 阅读1分钟

1.小明买礼物:a,b两种礼物各n,m个,每个盒子必须要有一个a,一个b,求最多能装几个?

let dataGroup = read_line();//这里的read_line()是赛码网上js使用的处理输入的api
let arr = [],
  line;
while (dataGroup >= 1) {
  line = read_line();
  arr.push(line.split(" "));
  dataGroup--;
}
let arr2 = [];
for (let item of arr) {
  let min = (item[0] * 1 + item[1] * 1) / 3;
  arr2.push(Math.min(item[0], item[1], min));
}
while (arr2.length) {
  console.log(arr.shift());
}

2.小名做实验,有一个纸带上有若干个数字,在纸带上选择一个位置k,k是分割点;k左边大于等于0的点为异常点,k右边小于等于0的点为异常点(纸袋上的数字只有0,-1,1,显然0不管在哪边都是异常点),现在给一个纸带,不给k,异常点最少个数为多少?

//let inputNum = read_line(),
//  arr1 = [];
//while ((line = read_line())) {
//  arr1 = line.split(" ");
//}
//为了方便在VSCODE上调试,我这里直接自定义了输入
let arr1 = [0, -1, -1, 1, -1, 1, 0, 0, -1, 1];
let zeroCount = 0;
let min = Infinity,
  res,
  sum = 0;
var find = function (arr, findNum) {
  let count = 0;
  for (let i of arr) {
    if (i == findNum) count++;
  }
  return count;
};
//对数组去0,并且计zeroCount,因为0不管在左边还是右边都是异常点
for (let i = 0; i < arr1.length; i++) {
  if (arr1[i] == 0) {
    arr1.splice(i, 1);
    zeroCount++;
  }
}
//遍历去0后的数组寻找k
//这里比较关键,是整个题最重要的思路,对数组从左到右进行累加,记录累加到的最小值和所在位置,这个位置就是k
for (let i = 0; i < arr1.length; i++) {
  sum += arr1[i];
  if (sum < min) {
    min = sum;
    res = i;
  }
}
//得到k后分成两个数组,分别调用之前定义的find方法,加和得到最小异常点
let leftArr = arr1.slice(0, res);
let rightArr = arr1.slice(res);
console.log(find(leftArr, 1) + find(rightArr, -1) + zeroCount);

3.小名有n块魔法石,每块魔法石都有正反两面,每一面都刻有一个魔法阵,初始状态下,n块魔法石都是正面向上。这n块魔法石的能量刚好可以构建一个大型魔法阵,但是需要至少一般的魔法石向上的一面铭刻的阵法相同才能触发大型魔法阵的效果。小名希望反转最少数量的魔法石,使得这个大型魔法阵被触发,请问她最少需要翻转多少块魔法石。

var mapGenarate = function (map, arr, max) {
  for (let i of arr) {
    if (map.has(i)) {
      map.set(i, map.get(i) + 1);
      if (map.get(i) >= max) return 0;
    } else {
      map.set(i, 1);
    }
  }
  return map;
};
var findSame = function (arr1, arr2) {
  let map = new Map();
  for (let i = 0; i < arr1.length; i++) {
    if (arr1[i] === arr2[i]) {
      if (map.has(arr1[i])) {
        map.set(arr1[i], map.get(arr1[i]));
      } else {
        map.set(arr1[i], 1);
      }
    }
  }
  return map;
};

let num1 = [1, 1, 1, 2, 1, 1, 4, 5, 2];
let num2 = [2, 1, 1, 3, 3, 8, 9, 10, 3];
let max = Math.ceil(num1.length / 2);
let map1 = new Map();
let map2 = new Map();
let arr = [];

let minusMap = findSame(num1, num2);
map1 = mapGenarate(map1, num1, max);
map2 = mapGenarate(map2, num2, max);
if (map1 == 0 || map2 == 0) console.log(0);
else {
  //符合大于总数一半的数字的front,back值
  map1.forEach((value, key) => {
    if (map2.has(key) && map2.get(key) + value >= max) {
      let minus = minusMap.has(key) ? minusMap.get(key) : 0;
      arr.push(map2.get(key) - minus, value - minus);
    }
  });
  if (arr.length > 0) {
    console.log(Math.min(...arr));
  } else console.log(-1);
}

4.初始字符串为MetTuan,每次对字符串做 str = str + str.reverse() + "wow"的操作,无限循环。后面给你一个k,问你位置k的字符为什么。 找规律

let str = "MeiTuan";
str = str + Array.from(str).reverse().join("") + "wowwow";
//此时字符串为最小循环单位,有20个字符,不太明白的可以自己试试多重复几次
let k = 101;
let num = (k % 20) - 1;

console.log(str[num]);