
黑白图像常采用灰度图的方式存储,即图像的每个像素填充一个灰色阶段值,256节阶灰图是一个灰阶值取值范围为0-255的灰阶矩阵,0表示全黑,255表示全白,范围内的其他值表示不同的灰度。
但在计算机中实际存储时,会使用压缩算法,其中一个种压缩格式描述如如下:
10 10 255 34 0 1 255 8 0 3 255 6 0 5 255 4 0 7 255 2 0 9 255 21
所有的数值以空格分隔; 前两个数分别表示矩阵的行数和列数; 从第三个数开始,每两个数一组,每组第一个数是灰阶值,第二个数表示该灰阶值从左到右,从上到下(可理解为二维数组按行存储在一维矩阵中)的连续像素个数。比如题目所述的例子, “255 34” 表示有连续 34 个像素的灰阶值是 255。 如下图所:连续34个255,1个0 再来连续8个255。

如此,图像软件在打开此格式灰度图的时候,就可以根据此算法从压缩数据恢复出原始灰度图矩阵。
请从输入的压缩数恢复灰度图原始矩阵,并返回指定像素的灰阶值。
输入描述:
输入包行两行,第一行是灰度图压缩数据,第二行表示一个像素位置的行号和列号,如 0 0 表示左上角像素。
备注:
1、系保证输入的压缩数据是合法有效的,不会出现数据起界、数值不合法等无法恢复的场景;
2、系统保证输入的像素坐标是合法的,不会出现不在矩阵中的像素;
3、矩阵的行和列数范图为:(0,100];
4、灰阶值取值范图:[0,255];
输出描述:输出数据表示的灰阶矩阵的指定像素的灰阶值。
10 10 255 34 0 1 255 8 0 3 255 6 0 5 255 4 0 7 255 2 0 9 255 21
3 4
99// line = '10 10 255 34 0 1 255 8 0 3 255 6 0 5 255 4 0 7 255 2 0 9 255 21'
// cords = '3 4'
function grayGraph (line, cords) {
let lineSplit = line.split(' ').map(Number);
let w = lineSplit[0];
let h = lineSplit[1];
let graph = lineSplit.slice(2);
const imageMatrix = [];
for (let i = 0; i < w; i++) {
imageMatrix[i] = new Array(h).fill(0);
}
let currentRow = 0;
let currentCol = 0;
let index = 0;
while (index < imageMatrix.length) {
let value = graph[index]
let count = graph[index + 1];
index += 2;
for (let i = 0; i < count; i++) {
imageMatrix[currentRow][currentCol++] = value;
if (currentCol === h) { // 换行
currentRow++;
currentCol = 0;
}
}
}
console.log(imageMatrix);
let [row, col] = cords.split(' ').map(Number);
console.log(imageMatrix[row][col]);
}智能手机方便了我们生活的同时,也侵占了我们不少的时间。“手机App防沉迷系统” 能够让我们每天合理的规划手机App使用时间,在正确的时间做正确的事
它的大概原理是这样的:
在一天24小时内,可注册每个App的允许使时段;
一个时间段只能使用一个APP, 不能在同时注册App2 和 App3;
App有优先级,数值越高,优先级越高。注册使用时段时,如果高优先级的App时间和低优先级的时段有冲突,则系统会自动注销低优先级的时段;
如果App的优先级相同,则后添加的App不能注册。
请编程实现,根据输入数据注册App,并根据输入的时间点,返回时间点注册的App名称,如果该时间点没有注册任何App,请返回字符串“NA"。
输入描述:
(N≤100)2
App1 1 09:00 10:00
App2 2 11:00 11:30
09:30
数据说明如下
1、N行注册数据以空格分隔,四项数依次表示: App名称、优先级、起始时间,结束时间
2.优先级1-5,数字值越大,优先级越高
3、时间格式HH:MM,小时和分钟都是两位,不足两位前面补0
4.起始时间需小于结束时间,否则注册不上
5.注册信息中的时间段包含起始时间点,不包含结束时间点输出描述:输出一个字符串,表示App名称,或NA表示空闲时间。
输入:
1
App1 1 09:00 10:00
09:30
输出:
App1
说明:
App1注册在9点到10点间,9点半可用的应用名是App1
输入:
2
App1 1 09:00 10:00
App2 2 09:10 09:30
09:20
输出:
App2
说明:
ApP1和App2的时段有冲突,App2优先级高,注册App2之后,App1自动注销,因此输出App2题解
这是一个模拟题,需要按照题目描述的规则模拟注册过程,并在给定时间点找到注册的App。
程序的解题思路和关键步骤:
定义一个App类,用于表示应用程序对象,包括应用程序名称、优先级、开始时间和结束时间。同时,在App类中实现一个方法判断两个应用程序对象是否有时间重叠。
编写convertToMinutes方法,将时间字符串转换为分钟表示的整数。
编写convertToApp方法,将输入的字符串转换为应用程序对象。
通过读取输入,获取应用程序的数量,以及每个应用程序的注册信息。将注册信息转换为App对象,并根据题目规则进行注册。如果新注册的应用程序与已有的应用程序有时间重叠,根据优先级判断是否需要注销低优先级的应用程序。
读取给定的时间点,将其转换为分钟表示的整数。
遍历已注册的应用程序列表,找到包含给定时间的应用程序。
输出结果。
该程序使用了类的封装和集合的操作,通过遍历和比较,实现了应用程序的注册和冲突处理。最后,根据给定时间点找到相应的应用程序并输出结果。
时间复杂度:O(N^2),其中N为应用程序的数量。在每次注册应用程序时,都需要遍历已有的应用程序列表,判断是否有时间重叠。
空间复杂度:O(N),存储了已注册的应用程序列表// appNums = 2
// appUseDataStr = ['App1 1 09:00 10:00', 'App2 2 11:00 11:30']
// time = '09:30'
function convertTime (timeStr) {
const [hours, minutes] = timeStr.split(':').map(Number);
return hours * 60 + minutes;
}
function appUseTime (appNums, appUseDataStr, time) {
const apps = appUseDataStr.map(value => {
let split = value.split(' ');
return {
name: split[0],
priority: parseInt(split[1]),
startTime: convertTime(split[2]),
endTime: convertTime(split[3]),
}
})
let queryTime = convertTime(time);
const registerApps = [];
for (let i = 0; i < apps.length; i++) {
let app = apps[i];
if (app.startTime > app.endTime) {
continue;
}
for (let j = registerApps.length - 1; j >= 0; j--) {
let registerApp = registerApps[j];
if (Math.max(app.startTime, registerApp.startTime) < Math.min(app.endTime, registerApp.endTime)) {
if (app.priority > registerApp.priority) {
// 注销优先级低的应用
registerApps.splice(j, 1);
} else {
// 优先级不高,继续检查下一个已注册app
continue;
}
}
}
registerApps.push(app);
}
let result = 'NA'
for (let app of registerApps) {
if (queryTime >= app.startTime && queryTime < app.endTime) {
result = app.name;
break;
}
}
console.log(result);
}幼儿园组织活动,老师布置了一个任务:
每个小朋友去了解与自己同一个小区的小朋友还有几个。
我们将这些数量汇总到数组 garden 中。
请根据这些小朋友给出的信息,计算班级小朋友至少来自几个小区?
输入描述:
输入:garden[] = 3
输出描述:
输出:7
const readline = require('readline');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
})
rl.on('line', (line) => {
const input = line.split(' ');
const zones = new Array(1000).fill(0);
let result = 0;
let index = 0;
while (true) {
if (index >= input.length) {
break;
} else {
zones[input[index]] += 1;
}
index += 1;
}
for (let i = 0; i < 1000; i++) {
if (zones[i] <= 0) {
continue;
} else {
let total = Math.ceil(zones[i] / (i + 1));
result += total * (i + 1);
}
}
console.log(result);
rl.close();
})
function aaa ([2, 2, 3]) {
const zones = new Array(1000).fill(0);
let result = 0;
let index = 0;
while (true) {
if (index >= input.length) {
break;
} else {
zones[input[index]] += 1;
}
index += 1;
}
for (let i = 0; i < 1000; i++) {
if (zones[i] <= 0) {
continue;
} else {
let total = Math.ceil(zones[i] / (i + 1));
console.log(total, i + 1, total * (i + 1));
result += total * (i + 1);
}
}
console.log(result);
}某个产品当前迭代周期内有N个特性(F1, F2, ..., FN)需要进行覆盖测试,每个特性都被评估了对应的优先级,特性使用其ID作为下标进行标识。
设计了M个测试用例(T1, T2,...,TM),每个用例对应了一个覆盖特性的集合,测试用例使用其ID作为下标进行标识,测试用例的优先级定义为其覆盖的特性的优先级之和。
在开展测试之前,需要制定测试用例的执行顺序,规则为:优先级大的用例先执行,如果存在优先级相同的用例,用例ID小的先执行。
输入描述:
输出描述:按照执行顺序(优先级从大到小)输出测试用例的ID,每行一个ID。
输入:5 4
1
1
2
3
5
1 2 3
1 4
3 4 5
2 3 4
输出:3 4 1 2
说明:测试用例的优先级计算如下:
T1=Pf1+Pf2+Pf3=1+1+2=4
T2=Pf1+Pf4=1+3=4
T3=Pf3+Pf4+Pf5=2+3+5=10
T4=Pf2+Pf3+Pf4=1+2+3=6
按照优先级从小到大,以及相同优先级,ID小的先执行的规则,执行顺序为T3,T4,T1,T2const readline = require('readline');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
})
let inputs = []
rl.on('line', (line) => {
inputs.push(line);
}).on('close', () => {
let [M, N] = inputs.shift().split(' ').map(Number);
let featuresNums = inputs.slice(0, N).map(Number);
let testCases = inputs.slice(N).map((line, index) => {
let sum = line.split(' ').reduce((acc, cur) => {
return acc + featuresNums[index];
})
return {
id: index + 1,
priority: sum,
}
})
testCases.sort((a, b) => {
return b.proiority - a.priority || a.id - b.id;
})
testCases.forEach(testCase => {
console.log(testCase.id)
})
})疫情期间,小明隔离在家,百无聊赖,在纸上写数字玩。他发明了一种写法:
给出数字个数n和行数m (0 < n <= 999,0 < m <= 999),从左上角的1开始,按照顺时针螺旋向内写方式,依次写出2,3...n,最终形成一个m行矩阵。
小明对这个矩阵有些要求:
输入描述:两个整数,空格隔开,依次表示n、m
输出描述:符合要求的唯一矩阵
输入:
9 4
输出:
1 2 3
* * 4
9 * 5
8 7 6
说明:
9个数字写成4行,最少需要3列
输入:
3 5
输出
1
2
3
*
*
说明
3个数字写5行,只有一列,数字不够用*号填充这是一个模拟题,主要考察对矩阵的遍历和填充的能力。
首先,通过输入获取数字个数n和行数m。
计算矩阵的列数cols,根据题意,最少需要的列数是(n-1) / m + 1。
初始化一个大小为m行cols列的矩阵,所有元素初始值为"*"。
使用四个变量top、bottom、left、right来表示当前矩阵的上下左右边界。
使用cur变量表示当前要填充的数字,从1开始。
进入循环,按照顺时针螺旋的方式依次填充矩阵的数字。
从左到右:遍历当前行的左右范围,依次填充数字。
从上到下:遍历当前列的上下范围,依次填充数字。
从右到左:遍历当前行的右左范围,依次填充数字。
从下到上:遍历当前列的下上范围,依次填充数字。
在每次填充后,更新相应的边界。
循环直到所有数字都填充完毕。
最后,输出填充好的矩阵。
这样,通过模拟顺时针螺旋填充的过程,就能得到符合要求的矩阵。// m 行数
// n 数字个数
function getRoundArr (m, n) {
let cols = Math.ceil(n / m);
let matrix = Array.from({ length: m }, () => {
return Array(cols).fill('*')
})
let start = 1;
let top = 0;
let bottom = m - 1;
let left = 0;
let right = cols - 1;
while (start <= n) {
// 从左到右
for (let i = left; i <= right && start <= n; i++) {
matrix[top][i] = start++;
}
top++; // 上边界下移动
// 从上到下
for (let i = top; i <= bottom && start <= n; i++) {
matrix[i][right] = start++;
}
right--;
// 从右到左
for (let i = right; i >= left && start <= n; i--) {
matrix[bottom][i] = start++;
}
bottom--;
// 从下到上
for (let i = bottom; i >= top && start <= n; i--) {
matrix[i][left] = start++;
}
left++;
}
console.log(matrix);
}有一个总空间为100字节的堆,现要从中新申请一块内存,内存分配原则为:
优先分配紧接着前一块已使用的内存,分配空间足够时分配最接近申请大小的空闲内存。
输入描述:
输出描述:
备注:
输入:
1
0 1
3 2
输出:
1
说明:
堆中已使用的两块内存是偏移从0开始的1字节和偏移从3开始的2字节,空闲的两块内存是偏移从1开始2个字节和偏移从5开始95字节根据分配原则,新申请的内存应从1开始分配1个字节,所以输出偏移为1。const readline = require('readline');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
})
let mallocSize; // 需要分配的内存大小
let useMemory = []; // 已分配的内存
rl.on('line', (line) => {
if (!mallocSize) {
mallocSize = parseInt(line.trim());
if (mallocSize <= 0 || mallocSize > 100) {
console.log(-1)
process.exit(0);
}
} else {
const memoryBlock = line.split(' ').map(Number);
useMemory.push(memoryBlock);
}
}).on('close', () => {
useMemory.sort((a, b) => a[0] - b[0]);
let start = 0;
let bestFitStart = -1;
let minSizeDiff = Number.MAX_SAFE_INTEGER;
for (let block of useMemory) {
let blockStart = block[0];
let blockSize = block[1];
if (blockStart < start || blockStart <= 0 || blockStart + blockSize > 100) {
console.log(-1)
process.exit(0);
}
let freeSpace = blockStart - start
// 空闲空间
if (mallocSize <= freeSpace && (freeSpece - mallocSize) < minSizeDiff) {
bestFitStart = blockStart;
minSizeDiff = freeSpace - mallocSize;
}
start = blockStart + blockSize;
}
// 检查最后一个内存块是否有足够空间
if (100 - start >= mallocSize && (100 -start-mallocsize) < minSizeDiff) {
bestFitStart = start;
}
console.log(bestFitStart)
})M(1<=M<=20)辆车需要在一条不能超车的单行道到达终点,起点到终点的距离为N(1<=N<=400)。速度快的车追上前车后,只能以前车的速度继续行驶。求最后一车辆到达目的地花费的时间。
注:每辆车固定间隔一小时出发,比如第一辆车0时出发,第二辆车1时出发,以此类推
输入描述:
0<S<30。输出描述:
最后一辆车到达目的地花费的时间
2 11
3
2
输出 5.5const readline = require('readline');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
})
let inputs = []
rl.on('line', (line) => {
lines.push(line)
}).on('close', () => {
const [M, N] = lines[0].split(' ').map(Number)
const speeds = lines.slice(1, M + 1).map(Number)
const arrivalTimes = new Array(M).fill(0)
arrivalTimes[0] = N / speeds[0]
for (let index = 1; index < M; index++) {
const currentTime = N / speeds[index] + index;
if (currentTime > arrivalTimes[index - 1]) {
arrivalTimes[index] = currentTime;
} else {
arrivalTimes[index] = arrivalTimes[index - 1];
}
}
console.log(arrivalTimes[M - 1] - M + 1)
})