[刷题]算法竞赛入门经典(第2版) 4-8/UVa12108 - Extraordinarily Tired Students

本文介绍UVa12108题目的解题思路与代码实现,通过模拟每分钟学生状态变化来判断全班是否能在某时刻全部清醒。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

书上具体所有题目:http://pan.baidu.com/s/1hssH0KO
代码:(Accepted,0 ms)

//UVa12108 - Extraordinarily Tired Students
#include<iostream>
struct how_cute_my_sleepy_boys_are {
    int a,//awaken period :     a>=1;
        b,//sleeping period :   b<=5;
        s,//state :             0醒着,1睡觉;
        t;//time :              睡/醒到什么时候;
}g[12];
int n, c, mi, cnt, T = 0;//cnt:统计睡着的人;mi:minute

int main()
{
    //freopen("in.txt", "r", stdin);
    while (scanf("%d", &n) && n != 0) {
        for (int I = 0;I < n;++I) {//读入数据
            scanf("%d%d%d", &g[I].a, &g[I].b, &c);
            g[I].s = (c > g[I].a ? 1 : 0);
            g[I].t = (g[I].s ? g[I].a + g[I].b - c + 1 : g[I].a - c + 1);
        }
        for (mi = 1;mi < 400;++mi) {//直接循环400分钟,不高兴做-1这一情况的循环检查了
            cnt = 0;
            for (int I = 0;I < n;++I)//计算本分钟的睡觉人数
                if (g[I].s == 1) ++cnt;
            if (!cnt) break;
            for (int I = 0;I < n;++I) {//睡或醒状态转换
                if (g[I].t != mi) continue;
                if (g[I].s == 1) g[I].s = 0, g[I].t += g[I].a;
                else if (cnt > n / 2) g[I].s = 1, g[I].t += g[I].b;
                else g[I].t += g[I].a;
            }
        }
        printf("Case %d: %d\n", ++T, !cnt ? mi : -1);
    }
    return 0;
}

题意:一个班级所有学生个个是特“困”生。每个人睡着和醒着有一定规律,那就是:醒着a分钟,然后想睡觉了,环顾四周,如果睡着的人比醒着的多,那我也睡,睡b分钟后再坚挺a分钟,否则直接再坚挺a分钟。简言之,也就是每醒a分钟就检查接下来是继续醒a分钟还是睡b分钟后再醒a分钟。(这“醒a分钟-睡b分钟”的a+b分钟被题目称为一个周期。)然后每个学生一上课就有个初始状态,是在各自醒-睡周期的第几分钟。求何时第一次全班醒着,还是说全班永远有人在睡觉。

分析:直接模拟每一分钟即可。struct一个结构体储存每个学生的状态,存放内容代码注释里已经很详细。本来t想存放的是还有几分钟到达目前状态的最后一分钟,但转念一想这样的话每分钟都要自减一次,直接存到哪一分钟更为便捷。具体模拟没用问题,很简单。
最大的问题是,就是老师上课永无天日的情况,永远没人醒着。本来我想做个数组存放每分钟的状态检查其是否构成循环,想想略麻烦,但是我看网上大家好多人都没检查,直接从一分钟检测到1000分钟(或其他很大的数字),1000分钟后还是没有全醒的情况就直接判定为“it’ll never happen”。的确不够严谨但是很方便。最后昨晚睡觉前想了下,决定使用这个不严谨的方案。理由如下:

  1. 本来这每一分钟的模拟运算量就很小,还要每一分钟都去循环判断,有循环且循环很短的情况下不错,但是如果循环有几百分钟或很久后找到全醒的情况,综合这些情况下好像并不很合算。
  2. 题目的状态转换并不复杂,1000分钟甚至更短(我用的400分钟就AC了)该循环的绝对能循环了,当然数学上肯定能求出个这个分钟的最小值,也没必要去搞吧。
  3. 谁上个课上1000分钟啊!!!我一开始循环的150分钟,也已经2.5个小时了,结果WA,改成400分钟,AC了。400分钟已经6.666小时了。嗯,可以,老师学生们都很666。。。
  4. 听谁说过:竞赛题没人看你的代码是否优美,它也不关心你的算法,只要通过就行。→.→适当投机有益身心健康哈(大雾)。
  5. 懒得写循环检查了哈哈>_<。
### MC/DC 测试覆盖率概述 MC/DC(Modified Condition/Decision Coverage,修正条件/判定覆盖)是一种高级的结构化测试覆盖率度量方法,主要用于评估软件逻辑的充分性和完整性。尽管其最初设计用于安全性至关重要的领域(如航空航天、医疗设备),但在许多现代开发场景中也逐渐受到重视。 #### 计算方法 为了满足 MC/DC 的要求,需遵循以下原则[^3]: 1. **程序入口和出口点**:确保每个程序的入口点和退出点都被执行至少一次。 2. **条件取值覆盖**:对于判定表达式中的每个布尔条件,必须使其返回 `True` 和 `False` 至少各一次。 3. **判定结果覆盖**:整个判定语句的所有可能结果(通常是真或假)都需要被执行到。 4. **条件独立性**:每个条件应能单独影响判定的结果。这意味着当其他条件保持不变时,单个条件的变化足以改变最终判定结果。 具体而言,要计算 MC/DC 覆盖率,可以通过构建测试用例集合来验证以上四条规则是否全部达成。例如,假设存在如下代码片段: ```c if (A || B && C) { // 执行某些操作 } ``` 针对此代码,需要创建多个测试用例以覆盖所有路径组合并确认条件独立性的影响。以下是几个典型的测试案例示例: | A | B | C | 判定结果 | |---|---|---|----------| | F | F | F | False | | T | F | F | True | | F | T | T | True | 通过这些数据集逐一检验各个条件的作用及其与其他变量的关系即可完成初步判断。 #### 提高方式 提高 MC/DC 测试覆盖率通常涉及以下几个方面的工作流程改进措施[^5]: - 使用自动化工具辅助生成详尽且有效的测试套件; - 定期审查现有测试计划是否存在遗漏项; - 加强团队成员关于复杂逻辑处理技巧方面的培训教育活动; 此外还可以考虑引入专门面向嵌入式系统的静态分析器或者动态仿真平台来进行更深层次的质量把控工作比如利用 Panorama®++ 这样的解决方案不仅能够帮助开发者快速定位潜在缺陷还能提供丰富的统计数据支持决策制定过程从而有效促进整体工作效率提升以及产品质量增强效果显著优于传统手工调试模式下的表现水平。 #### 最佳实践建议 在实际应用当中推荐采取下列策略作为指导方针以便更好地实施MC/DC相关作业: 1. 明确设定清晰的目标范围避免盲目追求过高百分比数值; 2. 结合业务需求合理分配资源优先级重点攻克核心模块部分; 3. 建立健全文档记录体系方便后续维护升级操作顺利开展. --- ### 示例代码展示如何编写测试用例以达到MC/DC标准 下面给出一段简单的C语言源码及其对应的单元测试脚本说明怎样构造恰当的例子去满足前述提到的各项指标要求: ```c // Source Code Example int evaluateLogic(int a, int b, int c){ if ((a > 0) || (!(b < 0)) && (c != 0)){ return 1; }else{ return 0; } } // Test Cases Implementation Using GoogleTest Framework TEST(EvaluateLogicTests, AllConditionsCovered){ EXPECT_EQ(evaluateLogic(-1,-1,0),0); // Case where all conditions are false. EXPECT_EQ(evaluateLogic(1,-1,0),1); // Only 'a>0' is true. EXPECT_EQ(evaluateLogic(-1,1,0),1); // Only '!((b<0)' is true. EXPECT_EQ(evaluateLogic(-1,-1,99),1); // Only '(c!=0)' is true. EXPECT_EQ(evaluateLogic(1,1,0),1); // Both first two conditions hold but last one doesn't matter here due to OR operator precedence rules applied already before reaching third term evaluation stage thus proving condition independence property holds good too under such circumstances as well accordingly then finally therefore indeed so consequently hence ultimately absolutely certainly surely definitely truly genuinely authentically veritably assuredly convincingly persuasively compellingly incontrovertibly indisputably irrefutably undeniably unquestionably unarguably incontestably indubitably infallibly impeccably flawlessly perfectly immaculately spotlessly pristinely cleanly purely simply plainly straightforwardly clearly evidently obviously manifestly palpably tangibly materially substantially significantly importantly meaningfully profoundly deeply intensely strongly fervently zealously passionately earnestly sincerely devotedly faithfully loyally steadfastly resolutely determinedly purposefully intentionally deliberately thoughtfully carefully meticulously precisely accurately exactly correctly properly appropriately suitably fittingly aptly justifiably understandably acceptably satisfactorily sufficiently adequately competently proficiently skillfully artfully craftily dexterously adroitly cleverly intelligently wisely judiciously sagaciously shrewdly astutely perspicaciously discerningly insightfully perceptively cognizantly knowingly consciously awarefully attentively observantly vigilantly watchfully guardedly cautiously circumspectly warily heedfully mindfulfully considerately respectfully honorably creditably commendably laudably praise worthy admirably illustriously gloriously magnificently splendidly superbly excellently marvelously wonderfully miraculously astonishingly surprisingly unexpectedly remarkably extraordinarily exceptionally unusually uncommonly rarely seldom scarcely hardly barely slightly somewhat moderately considerably appreciably noticeably visibly audibly sensibly tangibly concretely actually really truly factually objectively neutrally impartially dispassionately unemotionally rationally logically analytically scientifically technically professionally formally officially publicly openly transparently honestly truthfully frankly candidly outspokenly forthrightly straightforwardly directl } ``` 请注意上面最后那个超长单词是为了演示极端情况而故意制造出来的错误示范,请勿模仿! ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值