特别困的学生(Extraordinarily Tired Students, ACM/ICPC Xi‘an 2006, UVa12108)rust解法

课堂上有n个学生(n≤10)。每个学生都有一个“睡眠-清醒”周期,其中第i个学生醒Ai分钟后睡Bi分钟,然后重复(1≤Ai,Bi≤5),初始时第i个学生处在他的周期的第Ci分钟。每个学生在临睡前会察看全班睡觉人数是否严格大于清醒人数,只有这个条件满足时才睡觉,否则就坚持听课Ai分钟后再次检查这个条件。问经过多长时间后全班都清醒。如果用(A,B,C)描述一些学生,则图4-11中描述了3个学生(2,4,1)、(1,5,2)和(1,4,3)在每个时刻的行为。
在这里插入图片描述有可能并不存在“全部都清醒”的时刻,此时应输出-1。

样例:
输入

3
2 4 1
1 5 2
1 4 3
3
1 2 1
1 2 2
1 2 3

输出

18
-1

分析:
后一分钟要以前一分钟的睡眼人数为依据。
当前状态和初始状态相同就表示不存在“全部都清醒”的时刻。

解法:

use std::io;
#[derive(Debug)]
struct Student {
    a: usize,
    b: usize,
    c: usize,
    d: usize,
}
fn main() {
    let mut buf = String::new();
    io::stdin().read_line(&mut buf).unwrap();
    let n: usize = buf.trim().parse().unwrap();
    let mut students: Vec<Student> = vec![];
    for _ in 0..n {
        let mut buf = String::new();
        io::stdin().read_line(&mut buf).unwrap();
        let v: Vec<usize> = buf.split_whitespace().map(|x| x.parse().unwrap()).collect();
        students.push(Student {
            a: v[0],
            b: v[1],
            c: v[2],
            d: v[2],
        });
    }
    //println!("{:?}", students);
    let mut time = 1;
    loop {
        let mut sleeping = 0;
        for s in students.iter() {
            if s.d > s.a {
                sleeping += 1;
            }
        }
        //println!("{:?} {} sleeping {}", students, time, sleeping);
        if sleeping == 0 {
            println!("{}", time);
            break;
        }
        for s in students.iter_mut() {
            if s.d == s.a && sleeping <= n - sleeping {
                s.d = 1;
            } else {
                s.d = s.d % (s.a + s.b) + 1;
            }
        }
        time += 1;
        //println!("{:?} {} sleeping {}", students, time, sleeping);
        let mut bsame = true;
        //检查当前状态是否和初始状态相同,相同就表示不存在“全部都清醒”的时刻
        for s in students.iter() {
            if s.d != s.c {
                bsame = false;
            }
        }
        if bsame {
            println!("-1");
            break;
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值