网站开发项目视频教程电商购物网站开发需求分析
题目描述
喊7是一个传统的聚会游戏。N个人围成一圈,按顺时针从1到N编号。编号为1的人从1开始喊数,下一个人喊的数字为上一个人的数字加1。但是,当将要喊出来的数字是7的倍数或者数字本身含有7时,不能把这个数字直接喊出来,而是要喊“过”。假定玩这个游戏的N个人都没有失误地在正确的时机喊了“过”,现在给定一个长度为N的数组,存储了打乱顺序的每个人喊“过”的次数,请把它还原成正确的顺序,即数组的第i个元素存储编号i的人喊“过”的次数。
输入输出
-  
输入:
- 一行,为空格分隔的喊“过”的次数,注意K(即喊到的最大数字,但题目中并不直接给出K)不超过200,而数字的个数即为N。
 
 -  
输出:
- 一行,为顺序正确的喊“过”的次数,也由空格分隔。
 
 
示例
-  
示例1:
- 输入:0 1 0
 - 输出:1 0 0
 
 -  
示例2:
- 输入:0 0 0 2 1
 - 输出:0 2 0 1 0
 
 
解题思路
- 读取输入:首先,读取输入的喊“过”的次数,并将其转换为整数列表。
 - 计算总数:计算总的喊“过”的次数,即输入数组的和。
 - 初始化变量: 
- 初始化一个结果列表,用于存储每个人喊“过”的正确次数,长度与输入数组相同。
 - 初始化当前数字和当前玩家索引。
 
 - 模拟喊数过程: 
- 从1开始模拟喊数的过程,直到喊“过”的次数达到总数。
 - 在模拟过程中,判断当前数字是否需要喊“过”(是7的倍数或含有7)。
 - 如果需要喊“过”,则减少剩余的“过”的次数,并增加当前玩家的喊“过”次数。
 - 每喊完一个数,移动到下一个玩家(使用模运算实现循环)。
 
 - 输出结果:将结果列表转换为字符串,并用空格连接后输出。
 
代码实现
import java.util.Arrays;
import java.util.Scanner;
import java.util.stream.Collectors;public class CallSevenReordering {public static void main(String[] args) {// 创建扫描器对象以读取输入Scanner scanner = new Scanner(System.in);// 读取输入的喊“过”次数,并转换为整数数组String[] inputArrayStr = scanner.nextLine().split(" ");int[] inputArray = new int[inputArrayStr.length];for (int i = 0; i < inputArrayStr.length; i++) {inputArray[i] = Integer.parseInt(inputArrayStr[i]);}// 计算总的“过”次数int totalOvers = Arrays.stream(inputArray).sum();// 初始化结果数组,用于存储按正确顺序的喊“过”次数int[] resultArray = new int[inputArray.length];// 初始化当前数字和当前玩家索引int currentNumber = 1;int currentIndex = 0;// 模拟喊数过程while (totalOvers > 0) {// 判断当前数字是否需要喊“过”if (currentNumber % 7 == 0 || String.valueOf(currentNumber).contains("7")) {resultArray[currentIndex]++; // 当前玩家喊“过”次数加1totalOvers--; // 剩余的“过”次数减1}// 更新当前数字和当前玩家索引currentNumber++;currentIndex = (currentIndex + 1) % inputArray.length;}// 输出结果数组System.out.print(Arrays.stream(resultArray).mapToObj(String::valueOf).collect(Collectors.joining(" ")));// 关闭扫描器scanner.close();}
}
 
代码解析
- 读取输入:使用
input().split()读取输入,并将其转换为整数列表a。 - 计算总数:使用
sum(a)计算总的喊“过”的次数s。 - 初始化变量: 
n为玩家数量,即输入数组的长度。p为结果列表,初始化为长度为n的零列表。i为当前数字,初始化为1。j为当前玩家索引,初始化为0。
 - 模拟喊数过程: 
- 使用
while循环,直到s(剩余的“过”的次数)为0。 - 在循环中,判断当前数字
i是否需要喊“过”。- 如果需要,则减少
s并增加当前玩家的喊“过”次数p[j]。 
 - 如果需要,则减少
 - 每次循环结束后,数字
i加1,并移动到下一个玩家(使用j = (j + 1) % n实现循环)。 
 - 使用
 - 输出结果:使用
join和map将结果列表p转换为字符串,并用空格连接后输出。 
运行实例解析
- 输入:
0 1 0 - 程序模拟喊数过程: 
- 1(不过)
 - 2(不过)
 - 3(不过)
 - 4(不过)
 - 5(不过)
 - 6(不过)
 - 7(过,当前玩家是1,但输入说1没过,所以这是给下一个玩家的,但这里模拟是为了验证总数)
 - 由于我们不知道确切的最大数,我们继续模拟直到用完所有的“过”: 
- 8(不过)
 - 9(不过,但当前玩家2应该在这里喊过,因为上一个7的倍数已经过了给2)
 - …(继续模拟,但这里我们省略中间步骤,因为我们已经知道2会喊1次过)
 
 
 - 输出:
1 0 0(表示编号1的人喊过1次,编号2和3的人没有喊过) 
注意:实际的模拟过程不需要我们确切地知道喊到了哪个数字,只需要知道每个人喊“过”的次数是否正确。由于输入已经给出了这些次数,我们的模拟主要是为了验证算法的正确性。在这个例子中,输入0 1 0直接告诉我们答案应该是1 0 0。
