美团
acm模式的输入输出 美团2021校招笔试-编程题(通用编程试题,第10场)
第一题
输入描述:
输入第一行仅包含三个正整数n,x,y,分别表示参赛的人数和晋级淘汰人数区间。(1<=n<=50000,1<=x,y<=n) 输入第二行包含n个整数,中间用空格隔开,表示从1号选手到n号选手的成绩。(1<=|a_i|<=1000)
输出描述:
输出仅包含一个整数,如果不存在这样的m,则输出-1,否则输出符合条件的最小的值。
输入
6 2 3
1 2 3 4 5 6
输出
3
let first = readline().split(' ')
let n = parseInt(first[0]), x = parseInt(first[1]), y = parseInt(first[2])
let arrs = readline().split(' ').map(item => parseInt(item))
arrs.sort( (a,b) => {return a - b} )
let l=0, r=n-1
while(l<=r) {
let mid = l + Math.floor((r-l) / 2)
let pass = n - mid, fail = mid
if(pass < x || fail > y){
r = mid - 1
} else if(pass > y || fail < x){
l = mid + 1
} else {
r = mid - 1
}
}
let pass = n - l
let fail = l
if((pass >= x && pass <= y) && (fail >= x && fail <= y)) {
print(arrs[l-1])
} else {
print(-1)
}
第二题
输入描述:
输入第一行仅包含一个正整数n,表示任意序列的长度。(1<=n<=20000) 输入第二行包含n个整数,表示给出的序列,每个数的绝对值都小于10000。
输出描述:
输出仅包含一个整数,表示最少的操作数量。
输入
5
-1 2 3 10 100
输出
103
let n = parseInt(readline()), count = 0
let arr = readline().split(' ').map(item => parseInt(item))
arr.sort((a,b) => a-b)
for(let i = 1; i <= n; i++) {
if(arr[i-1] !== i) {
count += Math.abs(arr[i-1] - i)
}
}
print(count)
第三题
输入描述:
第一行输入一个整数T(1<=T<=10),表示数据组数。 每组数据占四行,第一行输入一个整数N(1<=N<=500000); 第二行输入一个长度为N且仅包含数字0、1、2的字符串,第i个数字表示左起第i张餐桌已坐有的用餐人数; 第三行输入一个整数M(1<=M<=2N且保证排队的每个人进入食堂时都有可供选择的餐桌); 第四行输入一个长度为M且仅包含字母M、F的字符串,若第i个字母为M,则排在第i的人为男性,否则其为女性。
输出描述:
每组数据输出占M行,第i行输出一个整数j(1<=j<=N),表示排在第i的人将选择左起第j张餐桌用餐。
输入:
1
5
01102
6
MFMMFF
输出:
2
1
1
3
4
4
直接使用写好的小顶堆
class PriorQueue {
constructor(mark) {
this.heap = []
this.mark = mark
}
getParent(index) {
return Math.floor((index-1)/2)
}
getLeft(index) {
return index * 2 + 1
}
getRight(index) {
return index * 2 + 2
}
compare(p, cur) {
if(this.mark=='min') {
return p > cur
} else {
return p < cur
}
}
swim(index) {
if(index==0) return
let parent = this.getParent(index)
while(parent>=0 && this.compare(this.heap[parent], this.heap[index])) {
this.swap(parent, index)
index = parent
parent = this.getParent(index)
}
}
insert(val) {
this.heap.push(val)
this.swim(this.heap.length-1)
}
sink(index) {
let left = this.getLeft(index)
while(left < this.heap.length) {
let right = this.getRight(index)
if(right<this.heap.length && this.compare(this.heap[left], this.heap[right])) left = right
if(this.compare(this.heap[index], this.heap[left])) {
this.swap(left, index)
index = left
left = this.getLeft(index)
} else {
break
}
}
}
pop() {
if(this.heap.length == 0) return undefined
if(this.heap.length == 1) return this.heap.shift()
let min = this.heap[0]
this.heap[0] = this.heap.pop()
this.sink(0)
return min
}
swap(p1, p2) {
[this.heap[p1], this.heap[p2]] = [this.heap[p2], this.heap[p1]]
}
peek() {
return this.heap[0]
}
size() {
return this.heap.length
}
}
let team = parseInt(readline())
while(team--) {
let num = parseInt(readline())
let s0 = new PriorQueue('min'), s1 = new PriorQueue('min'), s2 = new PriorQueue('min')
let table = readline()
for(let index=1; index<=table.length; index++ ){
let item = table.charAt(index-1)
if(item=='0') {
s0.insert(index)
} else if(item=='1'){
s1.insert(index)
} else{
s2.insert(index)
}
}
let res = []
let numPeople = parseInt(readline())
let people = readline()
for(let i=0; i<people.length; i++) {
let sex = people.charAt(i)
if(sex === 'M') {
if(s1.size()) {
res.push(s1.peek())
let out = s1.pop()
s2.insert(out)
}else {
res.push(s0.peek())
let out = s0.pop()
s1.insert(out)
}
} else {
if(s0.size()) {
res.push(s0.peek())
let out = s0.pop()
s1.insert(out)
} else {
res.push(s1.peek())
let out = s1.pop()
s2.insert(out)
}
}
}
res.forEach(item => console.log(item))
}
第四题 (做不出)
输入描述:
第一行输入一个整数N(1<=N<=300),表示二叉树的节点数。 第二行输入N个由空格隔开的整数,表示按中序遍历记录下的各个节点的权值,所有权值均为不超过1000的正整数。
输出描述:
输出一个整数,表示最优二叉树的总开销。
输入:
5
7 6 5 1 3
输出:
45
最优二叉树如图所示,总开销为7 * 1 + 6 * 5 + 5 * 1 + 1 * 3 = 45。
参考: 二叉树通常是递归的思想,主要没弄懂第三个参数root其实是代表上一层的父节点。
首先要明白中序遍历的特点:选取其中一个节点,其左边的节点都是其左子树上的节点,其右边的节点都是其右子树上的节点。
var n = parseInt(readline())
var table = new Array(n).fill(-1).map(item => new Array(n).fill(-1).map(item => new Array(n).fill(-1)))
var weight = readline().split(' ').map(item => parseInt(item))
function dfs(left, right, root) {
if(left > right) return 0
if(root>=0 && table[left][right][root]!=-1){
return table[left][right][root];
}
let cost = Number.MAX_VALUE
for(let i=left; i<=right; i++){
let leftCost=dfs(left,i-1,i);
let rightCost=dfs(i+1,right,i);
cost=Math.min(cost,leftCost + rightCost + weight[i] * (root != -1 ? weight[root] : 0));
}
if(root>=0){
table[left][right][root]=cost;
}
return cost;
}
let result = dfs(0, n-1, -1)
console.log(result)
|