题目:现在有n个人需要依次使用1个洗手池洗手,进行一步洗手需要1单位时间。他们每个人至少会进行一步洗手,但是却不一定进行了完整的七部洗手。
现在你知道了他们总共的洗手时间为t,请你推测他们有多少人进行了完整的七步洗手。
输入格式:一行两个整数n,t,依次代表人数和总洗手时间。
输出格式:一行两个整数,依次代表进行了完整七步洗手人数的最小值和最大值。
首先,最大值应该是比较容易想到的,用总时间t除以7再向下取整。设有一队伍站着的就是这些洗手的人,那么这种情况就是假设第一个人就进行了完整的七步洗手,第二个也是,第三个也是。。。直到检测完第i个人以后发现剩下的时间不足7时,那么前面i就是最大值。
最小值怎么求呢?
先假设他们都没有进行完整的七步洗手,从最不济的情况考虑,他们都洗了六步,那么总时间就是6*n,如果6*n等于t,那么他们就都洗了六步,最小值为0。如果t还比6n小,那么最小值就更是0了,这代表可能其中有人洗了五步,四步,或更少,这样总时间就比6n少了。也就是说,如果6n>=t,那么最小值是0;
再处理6n<t的情况。这种情况代表至少有一个人洗了七步。那么什么条件代表至少有、两个,三个甚至更多人洗了七步呢?
先假设已经确定有一个人洗了7步。用下图表示:【 】代表未确定洗手步骤的人。【n】表示已确定的洗手步骤为n的人。
【 】【 】【 】【 】【 】【 】【 】【 】 【7】
此时可以发现,洗了七步的人洗完以后,时间还剩t-7.人数还剩n-1。
此时就容易了。接续上面的思想,假设其余的n-1个人全部洗了6步:
【6】【6】【6】【6】【6】【6】【6】【6】 【7】
|<--------n-1个人,实际时长:6(n-1)--------->|
那么n-1个人的总时长就是6(n-1)。实际时长是t-7,如果6(n-1)==t-7,那么他们n-1个人就真的全部洗了六步(最不济的情况)!6(n-1)>t-7就更不用说了,此时代表可能其中有人洗了五步,四步,或更少,这样实际总时间就比6(n-1)少了。那么,如果6(n-1)<t-7,就代表除去已经确定的七步洗手的一个人以外,还有至少一个人洗了七步。
接下来就很简单了。已经确定有两个人洗了七步的情况:
【 】【 】【 】【 】【 】【 】【 】【7】【7】
“最不济的情况”:
【6】【6】【6】【6】【6】【6】【6】【7】 【7】
|<-----n-2个人,实际时长:6(n-2)---->|
当6(n-2)<t-2*7时,代表除去已经确定的七步洗手的两个人以外,还有至少一个人洗了七步。
以此类推,设已经确定的七步洗手人数为i,那么如果6(n-i)<t-7i,那么i还不够,要自增1.直到6(n-i)>=t-7i为止。这样的话,剩余的人中最不济的情况下不会有人洗了七步。“全部n个人都洗了六步”的那种情况下(一开始那种),i=0。
程序如下:
1 #include<iostream> 2 using namespace std; 3 int main() 4 { 5 int people,time; 6 cin>>people>>time; 7 int max=time/7; //这就是最大值 8 int min=0; 9 while((people-min)*6<time-7*min) //还有人洗了七步 10 { 11 min++; 12 } 13 cout<<min<<" "<<max; 14 return 0; 15 }