求幸存数之和
2025华为OD机试双机位C卷 - 华为OD上机考试双机位C卷 100分题型
华为OD机试双机位C卷真题目录点击查看: 华为OD机试双机位C卷真题题库目录|机考题库 + 算法考点详解
题目描述
给一个正整数数列 nums,一个跳数 jump,及幸存数量 left。
运算过程为:从索引0的位置开始向后跳,中间跳过 J 个数字,命中索引为 J+1 的数字,该数被敲出,并从该点起跳,以此类推,直到幸存 left 个数为止,然后返回幸存数之和。
约束:
- 0是第一个起跳点
- 起跳点和命中点之间间隔 jump 个数字,已被敲出的数字不计入在内。
- 跳到末尾时无缝从头开始(循环查找),并可以多次循环。
- 若起始时 left > len(nums) 则无需跳数处理过程。
输入描述
第一行输入正整数数列
第二行输入跳数
第三行输入幸存数量
输出描述
输出幸存数之和
用例1
输入
none
1,2,3,4,5,6,7,8,9
4
3
输出
none
13
说明
从1(索引为0)开始起跳,中间跳过 4 个数字,因此依次删除 6,2,8,5,4,7。剩余1,3,9,返回和为13
题解
思路:模拟
- 解析输入正整数序列,按照
,进行分割得到数组。 - 如果数组长度小于等于
left,不需要进行跳数,直接输出数组和就行。 - 数组长度大于
left情况,构建循环链表,按照题意进行处理即可(这部分可以参照下面代码),主要注意一个点:要移除链表某个节点,应该是有执行它前继节点的引用。 - 执行3的逻辑直到剩余节点数量等于
left结束,此时计算剩余节点和就是结果。
c++
c++
#include<iostream>
#include<vector>
#include<string>
#include <utility>
#include <sstream>
#include<algorithm>
#include<cmath>
#include<map>
#include<list>
using namespace std;
// 循环链表节点
struct Node {
int val;
Node* next;
Node(int v) : val(v), next(nullptr) {}
};
// 通用 切割函数 函数 将字符串str根据delimiter进行切割
vector<int> split(const string& str, const string& delimiter) {
vector<int> result;
size_t start = 0;
size_t end = str.find(delimiter);
while (end != string::npos) {
result.push_back(stoi(str.substr(start, end - start)));
start = end + delimiter.length();
end = str.find(delimiter, start);
}
// 添加最后一个部分
result.push_back(stoi(str.substr(start)));
return result;
}
int main() {
string input;
getline(cin, input);
int jumpCount;
cin >> jumpCount;
int left;
cin >> left;
vector<int> nums = split(input, ",");
int n = nums.size();
int sum = 0;
for (int i = 0; i < n; i++) {
sum += nums[i];
}
// 无需进行跳数处理
if (left >= n) {
cout << sum;
return 0;
}
// 构建循环链表
Node* head = new Node(nums[0]);
Node* prev = head;
for (int i = 1; i < n; i++) {
prev->next = new Node(nums[i]);
prev = prev->next;
}
// 成环
prev->next = head;
Node* cur = head;
int leftCount = n;
// 循环删除
while (leftCount > left) {
// 跳过 jump 个节点
for (int i = 0; i < jumpCount; i++) {
cur = cur->next;
}
// 删除 cur->next
Node* del = cur->next;
cur->next = del->next;
delete del;
leftCount--;
}
// 计算结果
int result = 0;
Node* p = cur->next;
for (int i = 0; i < left; i++) {
result += p->val;
p = p->next;
}
cout << result << "\n";
return 0;
}
JAVA
JAVA
import java.io.*;
import java.util.*;
// 循环链表节点
class Node {
int val;
Node next;
Node(int v) {
val = v;
next = null;
}
}
public class Main {
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
// 第一行:正整数数列(逗号分隔)
String line = br.readLine().trim();
String[] parts = line.split(",");
int n = parts.length;
int[] nums = new int[n];
int sum = 0;
for (int i = 0; i < n; i++) {
nums[i] = Integer.parseInt(parts[i]);
sum += nums[i];
}
// 第二行:跳数
int jumpCount = Integer.parseInt(br.readLine().trim());
// 第三行:幸存数量
int left = Integer.parseInt(br.readLine().trim());
// 无需进行跳数处理
if (left >= n) {
System.out.println(sum);
return;
}
// 构建循环链表
Node head = new Node(nums[0]);
Node prev = head;
for (int i = 1; i < n; i++) {
prev.next = new Node(nums[i]);
prev = prev.next;
}
// 成环
prev.next = head;
Node cur = head;
int leftCount = n;
// 循环删除
while (leftCount > left) {
// 跳过 jumpCount 个节点
for (int i = 0; i < jumpCount; i++) {
cur = cur.next;
}
// 删除 cur.next
Node del = cur.next;
cur.next = del.next;
leftCount--;
}
//计算结果
int result = 0;
Node p = cur.next;
for (int i = 0; i < left; i++) {
result += p.val;
p = p.next;
}
System.out.println(result);
}
}
Python
python
import sys
# 循环链表节点
class Node:
def __init__(self, v):
self.val = v
self.next = None
def main():
data = sys.stdin.read().strip().splitlines()
# 第一行:正整数数列
nums = list(map(int, data[0].split(",")))
n = len(nums)
# 第二行:跳数
jumpCount = int(data[1])
# 第三行:幸存数量
left = int(data[2])
total = sum(nums)
# 无需进行跳数处理
if left >= n:
print(total)
return
#构建循环链表
head = Node(nums[0])
prev = head
for i in range(1, n):
prev.next = Node(nums[i])
prev = prev.next
# 成环
prev.next = head
cur = head
leftCount = n
#循环删除
while leftCount > left:
# 跳过 jumpCount 个节点
for _ in range(jumpCount):
cur = cur.next
# 删除 cur.next
cur.next = cur.next.next
leftCount -= 1
# 计算结果
result = 0
p = cur.next
for _ in range(left):
result += p.val
p = p.next
print(result)
if __name__ == "__main__":
main()
JavaScript
js
'use strict';
const readline = require('readline');
// 创建 readline 接口
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
let lines = [];
// 逐行读取输入
rl.on('line', (line) => {
lines.push(line.trim());
});
// 输入结束后处理
rl.on('close', () => {
// 循环链表节点
class Node {
constructor(v) {
this.val = v;
this.next = null;
}
}
// 第一行:正整数数列(逗号分隔)
const nums = lines[0].split(',').map(Number);
const n = nums.length;
// 第二行:跳数
const jumpCount = parseInt(lines[1], 10);
// 第三行:幸存数量
const left = parseInt(lines[2], 10);
let sum = nums.reduce((a, b) => a + b, 0);
// 无需进行跳数处理
if (left >= n) {
console.log(sum);
return;
}
// 构建循环链表
let head = new Node(nums[0]);
let prev = head;
for (let i = 1; i < n; i++) {
prev.next = new Node(nums[i]);
prev = prev.next;
}
// 成环
prev.next = head;
let cur = head;
let leftCount = n;
// 循环删除
while (leftCount > left) {
// 跳过 jumpCount 个节点
for (let i = 0; i < jumpCount; i++) {
cur = cur.next;
}
// 删除 cur.next
cur.next = cur.next.next;
leftCount--;
}
// 计算结果
let result = 0;
let p = cur.next;
for (let i = 0; i < left; i++) {
result += p.val;
p = p.next;
}
console.log(result);
});
Go
go
package main
import (
"bufio"
"fmt"
"os"
"strconv"
"strings"
)
// 循环链表节点
type Node struct {
val int
next *Node
}
func main() {
in := bufio.NewReader(os.Stdin)
// 第一行:正整数数列
line, _ := in.ReadString('\n')
line = strings.TrimSpace(line)
parts := strings.Split(line, ",")
nums := make([]int, len(parts))
sum := 0
for i, s := range parts {
nums[i], _ = strconv.Atoi(s)
sum += nums[i]
}
// 第二行:跳数
var jumpCount int
fmt.Fscan(in, &jumpCount)
// 第三行:幸存数量
var left int
fmt.Fscan(in, &left)
n := len(nums)
// 无需进行跳数处理
if left >= n {
fmt.Println(sum)
return
}
//构建循环链表
head := &Node{val: nums[0]}
prev := head
for i := 1; i < n; i++ {
prev.next = &Node{val: nums[i]}
prev = prev.next
}
// 成环
prev.next = head
cur := head
leftCount := n
//循环删除
for leftCount > left {
// 跳过 jumpCount 个节点
for i := 0; i < jumpCount; i++ {
cur = cur.next
}
// 删除 cur.next
cur.next = cur.next.next
leftCount--
}
//计算结果
result := 0
p := cur.next
for i := 0; i < left; i++ {
result += p.val
p = p.next
}
fmt.Println(result)
}