求幸存数之和
2025华为OD机试双机位C卷 - 华为OD上机考试双机位C卷 100分题型
华为OD机试双机位C卷真题目录点击查看: 华为OD机试双机位C卷真题题库目录|机考题库 + 算法考点详解
题目描述
给一个正整数数列 nums,一个跳数 jump,及幸存数量 left。
运算过程为:从索引0的位置开始向后跳,中间跳过 J 个数字,命中索引为 J+1 的数字,该数被敲出,并从该点起跳,以此类推,直到幸存 left 个数为止,然后返回幸存数之和。
约束:
- 0是第一个起跳点
- 起跳点和命中点之间间隔 jump 个数字,已被敲出的数字不计入在内。
- 跳到末尾时无缝从头开始(循环查找),并可以多次循环。
- 若起始时 left > len(nums) 则无需跳数处理过程。
输入描述
第一行输入正整数数列
第二行输入跳数
第三行输入幸存数量
输出描述
输出幸存数之和
用例1
输入
1,2,3,4,5,6,7,8,9 4 3输出
13说明
从1(索引为0)开始起跳,中间跳过 4 个数字,因此依次删除 6,2,8,5,4,7。剩余1,3,9,返回和为13
题解
思路:模拟
- 解析输入正整数序列,按照
,进行分割得到数组。 - 如果数组长度小于等于
left,不需要进行跳数,直接输出数组和就行。 - 数组长度大于
left情况,构建循环链表,按照题意进行处理即可(这部分可以参照下面代码),主要注意一个点:要移除链表某个节点,应该是有执行它前继节点的引用。 - 执行3的逻辑直到剩余节点数量等于
left结束,此时计算剩余节点和就是结果。
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
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
importsys# 循环链表节点classNode:def__init__(self,v):self.val=v self.next=Nonedefmain():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)# 无需进行跳数处理ifleft>=n:print(total)return#构建循环链表head=Node(nums[0])prev=headforiinrange(1,n):prev.next=Node(nums[i])prev=prev.next# 成环prev.next=head cur=head leftCount=n#循环删除whileleftCount>left:# 跳过 jumpCount 个节点for_inrange(jumpCount):cur=cur.next# 删除 cur.nextcur.next=cur.next.nextleftCount-=1# 计算结果result=0p=cur.nextfor_inrange(left):result+=p.val p=p.nextprint(result)if__name__=="__main__":main()JavaScript
'use strict';constreadline=require('readline');// 创建 readline 接口constrl=readline.createInterface({input:process.stdin,output:process.stdout});letlines=[];// 逐行读取输入rl.on('line',(line)=>{lines.push(line.trim());});// 输入结束后处理rl.on('close',()=>{// 循环链表节点classNode{constructor(v){this.val=v;this.next=null;}}// 第一行:正整数数列(逗号分隔)constnums=lines[0].split(',').map(Number);constn=nums.length;// 第二行:跳数constjumpCount=parseInt(lines[1],10);// 第三行:幸存数量constleft=parseInt(lines[2],10);letsum=nums.reduce((a,b)=>a+b,0);// 无需进行跳数处理if(left>=n){console.log(sum);return;}// 构建循环链表lethead=newNode(nums[0]);letprev=head;for(leti=1;i<n;i++){prev.next=newNode(nums[i]);prev=prev.next;}// 成环prev.next=head;letcur=head;letleftCount=n;// 循环删除while(leftCount>left){// 跳过 jumpCount 个节点for(leti=0;i<jumpCount;i++){cur=cur.next;}// 删除 cur.nextcur.next=cur.next.next;leftCount--;}// 计算结果letresult=0;letp=cur.next;for(leti=0;i<left;i++){result+=p.val;p=p.next;}console.log(result);});Go
packagemainimport("bufio""fmt""os""strconv""strings")// 循环链表节点typeNodestruct{valintnext*Node}funcmain(){in:=bufio.NewReader(os.Stdin)// 第一行:正整数数列line,_:=in.ReadString('\n')line=strings.TrimSpace(line)parts:=strings.Split(line,",")nums:=make([]int,len(parts))sum:=0fori,s:=rangeparts{nums[i],_=strconv.Atoi(s)sum+=nums[i]}// 第二行:跳数varjumpCountintfmt.Fscan(in,&jumpCount)// 第三行:幸存数量varleftintfmt.Fscan(in,&left)n:=len(nums)// 无需进行跳数处理ifleft>=n{fmt.Println(sum)return}//构建循环链表head:=&Node{val:nums[0]}prev:=headfori:=1;i<n;i++{prev.next=&Node{val:nums[i]}prev=prev.next}// 成环prev.next=head cur:=head leftCount:=n//循环删除forleftCount>left{// 跳过 jumpCount 个节点fori:=0;i<jumpCount;i++{cur=cur.next}// 删除 cur.nextcur.next=cur.next.next leftCount--}//计算结果result:=0p:=cur.nextfori:=0;i<left;i++{result+=p.val p=p.next}fmt.Println(result)}