Before an Exam

Before an Exam

原题链接:https://www.luogu.com.cn/problem/CF4B?contestId=149617

题目背景

明天皮特将要考生物。他并不很喜欢生物,但在 d d d 天前他得知他将不得不参加此次考试。皮特严厉的父母勒令他立即复习,因此他在第 i i i 天将需要学习不少于 m i n T i m e i minTime_i minTimei 小时,不多于 m a x T i m e i maxTime_i maxTimei 小时。他们同时警告皮特:考试前一天,他将被检查他复习的完成情况。

因此,今天皮特的父母会要求他展示他考前复习的学习时间表。然而,他只记录这 d d d 天以来他复习所用的总计用时 s u m T i m e sumTime sumTime(小时).现在他希望知道他能否给他的父母展示一份时间表,包含 d d d 个数,每个数 s c h e d u l e i schedule_i schedulei 表示皮特第 i i i 天在复习生物上的用时(单位为小时),并应满足上文提及的要求。

题目输入

第一行包含两个数: d , s u m T i m e d,sumTime d,sumTime

( 1 ≤ d ≤ 30 , 0 ≤ s u m T i m e ≤ 240 ) \left(1\le d\le30,0\le sumTime\le240\right) (1d30,0sumTime240),意义如上所述。

接下来 d d d 行,每行两个数: m i n T i m e i , m a x t i m e i minTime_i,maxtime_i minTimei,maxtimei,两个数之间有一个空格,意义如上。 ( 0 ≤ m i n T i m e i ≤ m a x T i m e i ≤ 8 ) \left(0\le minTime_i\le maxTime_i\le8\right) (0minTimeimaxTimei8)

题目输出

如果有解,在单独一行输出 YES,换行,输出任意一种满足上文要求的解。如果无解,在单独一行中输出 NO

Translated by @B_1168, @ivyjiao, @bye_wjx。

题目描述

Tomorrow Peter has a Biology exam. He does not like this subject much, but $ d $ days ago he learnt that he would have to take this exam. Peter’s strict parents made him prepare for the exam immediately, for this purpose he has to study not less than $ minTime_{i} $ and not more than $ maxTime_{i} $ hours per each $ i $ -th day. Moreover, they warned Peter that a day before the exam they would check how he has followed their instructions.

So, today is the day when Peter’s parents ask him to show the timetable of his preparatory studies. But the boy has counted only the sum of hours $ sumTime $ spent him on preparation, and now he wants to know if he can show his parents a timetable $ sсhedule $ with $ d $ numbers, where each number $ sсhedule_{i} $ stands for the time in hours spent by Peter each $ i $ -th day on biology studies, and satisfying the limitations imposed by his parents, and at the same time the sum total of all $ schedule_{i} $ should equal to $ sumTime $ .

输入格式

The first input line contains two integer numbers $ d,sumTime $ ( $ 1<=d<=30,0<=sumTime<=240 $ ) — the amount of days, during which Peter studied, and the total amount of hours, spent on preparation. Each of the following $ d $ lines contains two integer numbers $ minTime_{i},maxTime_{i} $ ( $ 0<=minTime_{i}<=maxTime_{i}<=8 $ ), separated by a space — minimum and maximum amount of hours that Peter could spent in the $ i $ -th day.

输出格式

In the first line print YES, and in the second line print $ d $ numbers (separated by a space), each of the numbers — amount of hours, spent by Peter on preparation in the corresponding day, if he followed his parents’ instructions; or print NO in the unique line. If there are many solutions, print any of them.

样例 #1

样例输入 #1

1 48
5 7

样例输出 #1

NO

样例 #2

样例输入 #2

2 5
0 1
3 5

样例输出 #2

YES
1 4

解题思路

如果要每一天都满足要求的话,充要条件就是:
sum{ max[i] } <= sumTime
&&
sum{ min[i] } <= sumTime

接下来就是分配时长。

既然已经"YES"了,说明至少每一天 min[i] 是能够满足的,
所以先分配给每一天一个 min[i] ,使用了 minax[i][0] 这个数组储存每天的时长,接下来就循环判断了,
如果某一天能达到 max[i] ,就直接分配给他该天的最大时长,
就一直这样分配,直到出现不能取 max[i],就直接取剩余的 sumTime 即可。

后面的时长自然而然地就是 minax[i][0] 本身的值了。

代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>

using namespace std;

int d;
int sumtime;
int minax[100][2]={0};
int sum1 = 0,sum2 = 0;
int i;

int main()
{
    cin >> d >> sumtime;
    for(i = 0;i < d;i++)
    {
        cin >> minax[i][0] >> minax[i][1];
        sum1 += minax[i][0];
        sum2 += minax[i][1];
    }
      
    if(sumtime >= sum1 && sumtime <= sum2)
    {	
        cout << "YES" << endl;
        i = 0;
        sumtime -= sum1;
        while(sumtime)
        {
            if(sumtime > minax[i][1]-minax[i][0])
            {
                sumtime-=minax[i][1]-minax[i][0];
                minax[i][0]=minax[i][1];
            }
            else
            {
                minax[i][0]+=sumtime;
                sumtime=0;
            }
            i++;
        }
        for(i=0;i<d;i++)
        {
            cout<<minax[i][0]<<" ";
        }
    }
    else
    {
        cout<<"NO"<<endl;
        return 0;
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

GBK_UTF-8

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值