T117897 七步洗手法 / PJT1(洛谷)

题目:现在有n个人需要依次使用1个洗手池洗手,进行一步洗手需要1单位时间。他们每个人至少会进行一步洗手,但是却不一定进行了完整的七部洗手。

现在你知道了他们总共的洗手时间为t,请你推测他们有多少人进行了完整的七步洗手。

入格式:一行两个整数nt,依次代表人数和总洗手时间。

输出格式:一行两个整数,依次代表进行了完整七步洗手人数的最小值和最大值。

 

首先,最大值应该是比较容易想到的,用总时间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 }

 

posted @ 2020-01-30 15:44  梦中霜雪梨花白  阅读(235)  评论(0编辑  收藏  举报