喊7的次数重排
题目描述
喊7是一个传统的聚会游戏, N个人围成一圈, 按顺时针从1到N编号.
编号为1的人从1开始喊数, 下一个人喊的数字为上一个人的数字加1, 但是当将要喊出来的数字是7的倍数或者数字本身含有7的话, 不能把这个数字直接喊出来, 而是要喊"过".
假定玩这个游戏的N个人都没有失误地在正确的时机喊了"过", 当喊到数字K时, 可以统计每个人喊"过"的次数.
现给定一个长度为N的数组, 存储了打乱顺序的每个人喊"过"的次数, 请把它还原成正确的顺序, 即数组的第i个元素存储编号i的人喊" 过"的次数.
输入描述
输入为一行, 为空格分隔的喊"过"的次数, 注意K并不提供, K不超过200, 而数字的个数即为N.
输出描述
输出为一行, 为顺序正确的喊"过"的次数, 也由空格分隔.
示例1
输入:
0 1 0
输出:
1 0 0
说明: 一共只有一次喊"过", 那只会发生在需要喊7时, 按顺序, 编号为1的人会遇到7, 故输出1 0 0
.
示例2
输入:
0 1 2 0 0
输出:
0 2 0 1 0
说明: 一共有三次喊"过", 发生在 7 14 17
, 按顺序, 编号为2的人会遇到 7 17
, 编号为4的人会遇到14, 故输出 0 2 0 1 0
.
题解
Python
def main():
# 读取输入
# 确定有人数 n
# 确定总共喊了多少声
# 基于此, 就可以确定喊的顺序
pass_list = list(map(int, input().split()))
# 得到人数
num_people = len(pass_list)
assert 0 < num_people
# 喊过的总次数
total_passes = sum(pass_list)
# 喊过的条件是:
# 1. 当前数字是7的倍数
# 2. 当前数字中包含7
# 每个人真正喊过的次数
real_pass_list = [0] * num_people
# 当前的喊的数字 k, 注意数字是从1开始
current_num = 1
# 当前喊数的人在队列中的位置, 从0开始计数
current_person = 0
# 一直循环, 直到喊过的次数用完了
while total_passes > 0:
if current_num % 7 == 0 or "7" in str(current_num):
# 这个人要喊过
real_pass_list[current_person] += 1
total_passes -= 1
current_num += 1
current_person = (current_person + 1) % num_people
# 打印结果
print(" ".join(map(str, real_pass_list)))
if __name__ == "__main__":
main()
Rust
use std::io::{stdin, BufRead}; fn number_digits_contains(mut num: u32, digit: u8) -> bool { while num > 0 { let d = (num % 10) as u8; if d == digit { return true; } num /= 10; } false } fn solution() { // 读取输入 // 确定有人数 n // 确定总共喊了多少声 // 基于此, 就可以确定喊的顺序 let mut line = String::new(); let ret = stdin().lock().read_line(&mut line); assert!(ret.is_ok()); let pass_list: Vec<u32> = line .trim() .split_ascii_whitespace() .map(|s| s.parse().unwrap()) .collect(); // 得到人数 let num_people = pass_list.len(); assert!(0 < num_people); // 喊过的总次数 let mut total_passes: u32 = pass_list.iter().sum(); // 喊过的条件是: // 1. 当前数字是7的倍数 // 2. 当前数字中包含7 // 每个人真正喊过的次数 let mut real_pass_list: Vec<usize> = vec![0; num_people]; // 当前的喊的数字 k, 注意数字是从1开始 let mut current_num = 1; // 当前喊数的人在队列中的位置, 从0开始计数 let mut current_person = 0; // 一直循环, 直到喊过的次数用完了 while total_passes > 0 { if current_num % 7 == 0 && number_digits_contains(current_num, 7) { // 这个人要喊过 real_pass_list[current_person] += 1; total_passes -= 1; } current_num += 1; current_person = (current_person + 1) % num_people; } // 打印结果 let s = real_pass_list .into_iter() .map(|x| x.to_string()) .collect::<Vec<String>>() .join(" "); println!("{s}"); } fn main() { solution(); }