华为OD机试真题 - 求幸存数之和 (C++ & Python & JAVA & JS & GO)

求幸存数之和

2025华为OD机试双机位C卷 - 华为OD上机考试双机位C卷 100分题型

华为OD机试双机位C卷真题目录点击查看: 华为OD机试双机位C卷真题题库目录|机考题库 + 算法考点详解

题目描述

给一个正整数数列 nums,一个跳数 jump,及幸存数量 left。

运算过程为:从索引0的位置开始向后跳,中间跳过 J 个数字,命中索引为 J+1 的数字,该数被敲出,并从该点起跳,以此类推,直到幸存 left 个数为止,然后返回幸存数之和。

约束:

  1. 0是第一个起跳点
  2. 起跳点和命中点之间间隔 jump 个数字,已被敲出的数字不计入在内。
  3. 跳到末尾时无缝从头开始(循环查找),并可以多次循环。
  4. 若起始时 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

题解

思路:模拟

  1. 解析输入正整数序列,按照,进行分割得到数组。
  2. 如果数组长度小于等于left,不需要进行跳数,直接输出数组和就行。
  3. 数组长度大于left情况,构建循环链表,按照题意进行处理即可(这部分可以参照下面代码),主要注意一个点:要移除链表某个节点,应该是有执行它前继节点的引用。
  4. 执行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)
}
相关推荐
无限码力1 天前
华为OD机试双机位C卷 - 结对编程 (C++ & Python & JAVA & JS & GO)
华为od·华为od机考·华为od机试·华为od机试双机位c卷·华为od机考双机位c卷·华为od上机考试·华为od机试-结对编程
无限码力4 天前
华为OD机试双机位C卷统一考试题库清单(持续收录中)以及考点说明
华为od·华为od机考·华为od机试·华为od机试双机位c卷·华为od机考双机位c卷·华为od双机位c卷·华为od上机考试 双机位c卷
无限码力4 天前
华为OD机试真题 - 没有回文串 (C++ & Python & JAVA & JS & GO)
华为od·华为od机试真题·华为od机试·od机考·华为od上机考试·华为od-没有回文串
无限码力6 天前
华为OD机考真题 -【测试用例执行计划】 (C++ & Python & JAVA & JS & GO)
华为od·华为od机考·华为od机试真题·华为od机试·华为od上机考试·华为od机考真题
开开心心_Every7 天前
无广告干扰:简单好用文字LOGO设计工具
xml·java·网络·数据库·华为od·华为云·excel
我是华为OD~HR~栗栗呀8 天前
(华为od)21届-Python面经
java·前端·c++·python·华为od·华为·面试
无限码力8 天前
华为OD机试双机位C卷 - 采样过滤 (C++ & Python & JAVA & JS & GO)
华为od·华为od机考·华为od机试·华为od机试双机位c卷·华为od上机考试·华为od机考真题·华为od机试-采样过滤
Tony_yitao13 天前
15.华为OD机考 - 执行任务赚积分
数据结构·算法·华为od·algorithm
无限码力14 天前
华为OD机试真题 - 最长广播响应 (C++ & Python & JAVA & JS & GO)
华为od·华为od机试·od机考·华为od上机考试真题·华为od机试-最长广播响应·华为od-最长广播响应