华为OD E卷(100分)45-喊7的次数重排
前言
工作了十几年,从普通的研发工程师一路成长为研发经理、研发总监。临近40岁,本想辞职后换一个相对稳定的工作环境一直干到老, 没想到离职后三个多月了还没找到工作,愁肠百结。为了让自己有点事情做,也算提高一下自己的编程能力,无聊之余打算用一些大厂的编程题练练手。希望通过这些分享能够帮到一些人,也希望能和看到此文的大神们沟通交流,提升自己,更希望在此期间能够找到一份理想的工作。
题目描述
喊7是一个传统的聚会游戏。N 个人围成一圈,按顺时针从 1 到 N 编号。游戏规则如下:
- 编号为 1 的人从 1 开始喊数。
- 下一个人喊的数字为上一个人的数字加 1。
- 当将要喊出来的数字是 7 的倍数或者数字本身含有 7 时,不能直接喊出这个数字,而是要喊"过"。
- 假定所有人都没有失误地在正确的时机喊了"过"。
现在,给定一个长度为 N 的数组,存储了打乱顺序的每个人喊"过"的次数。你的任务是将它还原成正确的顺序,即数组的第 i 个元素应存储编号 i 的人喊"过"的次数。
输入
输入为一行,包含空格分隔的喊"过"的次数。数字的个数即为 N。
输出
输出为一行,包含顺序正确的喊"过"的次数,用空格分隔。
示例
示例1
输入
0 1 0
输出1 0 0
说明:一共只有一次喊"过",那只会发生在需要喊 7 时。按顺序,编号为 1 的人会遇到 7,故输出 1 0 0。注意:结束时的 K 不一定是 7,也可以是 8、9 等,喊过的次数都是 1 0 0。
示例2
输入
0 0 0 2 1
输出0 2 0 1 0
说明
一共有三次喊"过",发生在 7、14、17。按顺序,编号为 2 的人会遇到 7 和 17,编号为 4 的人会遇到 14,故输出 0 2 0 1 0。
解题思路
重演数7的过程,直到喊过的总次数达到输入的次数和为止。过程中记录每个人喊过的次数。
题解
Java实现
package huawei.e100;
import java.util.Arrays;
import java.util.Scanner;
/**
* @author arnold
* @date 2025年1月2日
* 喊7的次数重排
*/
public class T45 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
while(sc.hasNext()) {
String[] tmp = sc.nextLine().split(" ");
int[] data = new int[tmp.length];
int sum = 0;
for (int i = 0; i < data.length; i++) {
data[i] = Integer.parseInt(tmp[i]);
sum += data[i];
}
int[] res = run(data, sum);
for (int i = 0; i < res.length; i++) {
System.out.print(res[i] +" ");
}
System.out.println();
}
}
static int[] run(int[] data, int times) {
int[] res = new int[data.length];
Arrays.fill(res, 0);
int sum = 0;
int num = 0;
while (sum < times) {
for (int i = 0; i < data.length; i++) {
num++;
if(num %7 == 0 || (num+"").indexOf("7") > -1) {
res[i] += 1;
sum ++;
}
}
}
return res;
}
}