【题目描述】
鸡尾酒疗法,指“高效抗逆转录病毒治疗”。人们在鸡尾酒疗法的基础上又提出了很多种改进的疗法。为了验证这些治疗方法是否在疗效上比鸡尾酒疗法更好,可用通过临床对照实验的方式进行。假设鸡尾酒疗法的有效率为x,新疗法的有效率为y,如果y-x大于5%,则效果更好,如果x-y大于5%,则效果更差,否则称为效果差不多。下面给出n组临床对照实验,其中第一组采用鸡尾酒疗法,其他n-1组为各种不同的改进疗法。请写程序判定各种改进疗法效果如何。
【输入】
第一行为整数n(1<n<=20);其余n行每行两个整数,第一个整数是临床实验的总病例数(小于等于10000),第二个疗效有效的病例数。这n行数据中,第一行为鸡尾酒疗法的数据,其余各行为各种改进疗法的数据
【输出】
有n-1行输出,分别表示对应改进疗法的效果:如果效果更好,输出better;如果效果更差,输出worse;否则输出same。
【输入样例】
5
125 99
112 89
145 99
99 97
123 98
【输出样例】
same
worse
better
same
#include<iostream>
#include<cstdio>
using namespace std;
int main()
{
int n,x,y;
scanf("%d",&n);
double dj,dn;
scanf("%d %d",&x,&y);
dj=y/(double)x;
for(int i=2;i<=n;i++)
{
scanf("%d %d",&x,&y);
dn=y/(double)x;
if(dn-dj>0.05)
printf("better\n");
else if(dj-dn>0.05)
printf("worse\n");
else
printf("same\n");
}
return 0;
}
本文来自投稿,不代表本站立场,如若转载,请注明出处:

卧槽,这题我当年做的时候真被坑惨了,今天刷到突然想骂人。你光看那个“y-x大于5%”就离谱,我一开始以为是用整数直接比,比如125和99减一下什么的,结果wa了三次才反应过来要算比例。然后更绝的是,那个“5%”到底啥意思?是0.05还是5?题目写“大于5%”,但有效率本来就是小数,99/125=0.792,你跟我说5%?那不就是0.05吗?可总有憨憨把它当整数算,我寝室那哥们用int存了99和125,然后算99/125得到0,直接输出same,还跟我犟说没问题,真服了,最后看题解才闭嘴。 说到这题本身,逻辑倒是不难,但那个输入样例我第一遍愣是看反了。你仔细看,第一行5,然后五行数据,第一行125 99是鸡尾酒的,后面四行分别是112 89、145 99、99 97、123 98。输出四行:same worse better same。我拿计算器摁了一遍:112/89?不对,是89/112,约0.7946,鸡尾酒是99/125=0.792,差0.0026,不到5%,same没毛病。第二组145和99,99/145约0.6828,比鸡尾酒低了0.109,那就是worse。第三组99和97,97/99约0.9798,高了0.1878,better。最后一组123和98,98/123约0.7967,又差一点点,same。这玩意儿就是比大小,但坑就坑在浮点数精度。你拿double算还好,要是手贱用float,可能就够呛。我试过float算99/125和98/123,结果刚好卡在0.05边界附近,万幸没翻车,但听说有人用float直接wa得妈都不认识。 其实这题真正让我来气的是题面那句“如果y-x大于5%,则效果更好,如果x-y大于5%,则效果更差,否则称为效果差不多”。你这不是废话吗?直接说“差的绝对值小于等于5%就是same”不就完了?非得绕个弯子。还有那个“鸡尾酒疗法”,我第一次上课看到这名字还以为是让人喝酒,后来才知道是艾滋病那个“高效抗逆转录病毒治疗”。但你想啊,拿这种真实医疗数据当编程题,就有点不严谨。你一个实验总共就不到10000个病例,有效率差个百分之零点几,你跟我说“差不多”?统计学上不得做个显著性检验?t检验、卡方检验啥的,你好歹给个p值吧?直接拿差值阈值一刀切,这要是真拿去判断临床效果,怕不是要出医疗事故。当然我知道这是给新手练if-else,别较真,但就是忍不住想吐槽。 再聊个搞笑的,当年我们班有个同学,代码写得贼简洁,每行都对齐,注释也写一堆。结果他写的比较是: if (y - x > 0.05) cout 0.05) cout 0.05肯定不成立,就执行else输出same。然后他样例怎么跑都能过,因为better的情况同时打了better和same,但OJ只检查第一个?不对,OJ输出会多一行,直接PE。他当时还跑来问我,说自己逻辑明明对的,我一看笑死,这典型的分支条件写串了。其实这种错误太常见了,尤其是新手,总觉得两个if和if-else差不多,实际上差远了。这题就应该用else if,不然就跟我那同学一样,输出多个结果。 还有啊,这题输入第一行是n,然后n行数据,但输出只有n-1行。我就见过有人把第一组数据也用来输出,结果多了一行,然后对着样例莫名其妙。你仔细读题,“第一行为鸡尾酒疗法的数据”,后面才是改进疗法,所以循环得从第二行开始。这个也是考点吧,但题目没明说,就靠样例猜。说实话这种题真挺阴间的,它不考算法,考阅读理解。你要是语文不好,直接gg。 另外说说那个数据范围,总病例数小于等于10000,有效病例数没说范围,但肯定不能比总数大吧?不然有效率超过100%了。不过万一给个不合法数据呢?比如有效数大于总数,算出来y>1,那比较就不对了。但OJ数据一般没那么恶心,毕竟这是入门题。可我还是想说,为了严谨,写代码的时候最好判断一下,但真这么写的人估计脑子有病,因为题目不要求。 再说个关于浮点数比较的骚操作。有人为了避免浮点误差,直接用交叉相乘:比如鸡尾酒效率x=a/b,新疗法效率y=c/d,那么y-x > 0.05 等价于 c/d - a/b > 0.05,两边乘以bd(都正),就是cb - ad > 0.05*bd。同理x-y>0.05就是ad - cb > 0.05*bd。这样全用整数,不怕精度问题。这方法看着挺聪明,但我当年压根没想到,直接用double过了。后来看讨论区有个老哥说用float被卡了,他才用交叉相乘。我心想这不是标准解法吗?但教材上没教过,都是自己摸索。这题其实很简单,但能聊的坑不少。 还有那个“效果更好”“效果更差”的翻译,你直接音译成better/worse/same也就罢了,能不能把“差不多”翻译成“same”?感觉有点中式英语。不过无所谓,题目就这样。 我记得最清楚的是,当时有个论坛上有人发帖说“这题我用Python不用写if,直接一行数组索引”,下面一堆人怼他装逼。那人写的啥我忘了,好像是把比较结果放到列表里,用条件真假当索引,确实骚,但属于炫技,不推荐新手学。我那时候觉得Python跑OJ慢,死磕C++,现在想想真的傻,用Python写这题不就几行?但没办法,学校要求C++,信息学奥赛就这么变态,非要你用指针什么的,明明这些题用Python写起来像喝水一样简单。 对了,说到鸡尾酒疗法,我突然想到一个梗。我大学有个室友,听这名字以为疗法的意思是每天喝一杯鸡尾酒就能治病,还专门去查了配方,结果发现是抗逆转录病毒的药物组合,跟酒没半点关系。他当时那个尴尬,笑死我了。不过这也怪中文翻译,“鸡尾酒疗法”听着确实像喝酒,实际上是因为多种药物混合起来像一个调酒师调鸡尾酒,所以叫这名。你说这种知识对做题有用吗?没用,但记住了还挺有意思。 其实这题最大的问题不是代码,而是那个“5%”的阈值。你想啊,如果鸡尾酒有效率为90%,新疗法有效率是94%,差4个百分点,题目说“差不多”,然后判same。但临床上有效率从90%提到94%,那可是实打实的进步,对几千个病人来说多救好几十个呢。你用一个固定的5%一刀切,不考虑样本量和基线有效率,这科学吗?明显不科学。但你要是跟OI教练提这个,他肯定说:“你管那么多干嘛,题目怎么说你怎么写。”也是,竞赛就是做题,不是搞科研。 不过我还是要说一句,这种题放在“信息学奥赛一本通”的第一百多页,本质是教if-else和循环。但出题人非要把简单的事情复杂化,又是鸡尾酒又是临床实验,还整出个样例让你猜。我刚学的时候,根本想不到要先算第一行的数据,然后拿后面的每一行去跟它比。因为我那时候连数组都不会,就想着每读一行就输出,结果第一行读进来直接拿去跟后面的比了,完全搞反。后来看了书上的讲解才知道,得先把第一组数据存起来,或者先读进去,然后用后面的数据跟它比。这个“先存再用”的思想,其实比if-else本身更重要。很多新手栽就栽在这,不是不会比大小,是不知道怎么把第一组单独拿出来。 还有一点,这题的输入是“第一行为整数n,其余n行每行两个整数”,但题目说“第一行为鸡尾酒疗法的数据”,那意思就是总共n行数据里,第一行是鸡尾酒,后面n-1行是改进。所以读的时候,先读n,再读第一组,存起来,然后循环n-1次读后面的,每次算完就输出一行。这个流程很简单,但如果你没想明白,就会在循环次数上出错。比如我一开始循环到n,结果最后一行数据是我读的什么鬼?因为我把第一组也当成改进疗法了,导致输出多了一行。后来改成for(int i=1;i a >> b; double y = a * 1.0 / b; if (y - x > 0.05) cout