Обычный метод прямого использования цикла для поиска наибольшего количества дней может принести только 15 баллов, а затем время выполнения истекает.
#include <iostream>
using namespace std;
int main(){
int n,m,k,t=0;
cin>>n>>m>>k;
auto*data=new pair<int ,int>[n];
for(int i=0;i<n;i++){
cin>>data[i].first>>data[i].second;
t=t>data[i].first?t:data[i].first;
}
while(m>0&&t>k){
for(int i=0;i<n;i++){
if(t==data[i].first&&m>=data[i].second){
data[i].first--;
m-=data[i].second;
}
}
t=k;
int temp=t;
for(int i=0;i<n;i++){
t=t>data[i].first?t:data[i].first;
}
if(temp==t)
break;
}
cout<<t;
}
Переключитесь на максимальную кучу для хранения. Очередь приоритетов C++ реализована с помощью кучи. Ее можно использовать непосредственно здесь. Следующий код может получить 70 баллов, но ему все равно не хватает времени.
#include<iostream>
#include<queue>
using namespace std;
int main(){
int n,m,k,ti,ci;
priority_queue<pair<int,int>>heap;
cin>>n>>m>>k;
while(n--){
cin>>ti>>ci;
heap.push({ti,ci});
}
while(m>heap.top().second){
pair<int,int>top=heap.top();
heap.pop();
if(top.first==k)
break;
top.first--;
m-=heap.top().second;
heap.push(top);
}
cout<<heap.top().first;
}
Чтобы изменить идею, предыдущая идея заключалась в том, чтобы сокращать один за другим. Максимальная тестовая выборка достигала 1 миллиарда. Ее нельзя уменьшать один за другим. Сначала объедините все дни с одинаковым числом вместе и отсортируйте их от большего к меньшему, а затем объединить предыдущие.Количество дней уменьшается до последнего количества дней и ресурсы добавляются.Следующий код может получить 85 баллов.Ошибка
#include<iostream>
#include<map>
using namespace std;
int main(){
long long n,m,k,ti,ci,t;
map<long long,long long,greater<>>field;
cin>>n>>m>>k;
while(n--){
cin>>ti>>ci;
field[ti]+=ci;
}
for(auto it=field.begin();it!=field.end();it++){
if(it== prev(field.end())){
while(m>=it->second){
t--;
m-=it->second;
}
break;
}
auto next=it;
next++;
long long cost=it->second*(it->first-next->first);
if(m<cost||t==k)
break;
t=next->first;
m-=cost;
next->second+=it->second;
}
t=t>=k?t:k;
cout<<t;
}
После многих тестов я, наконец, обнаружил, что не следует выходить сразу, когда m < стоимость, потому что m может быть уменьшено снова, хотя и не может быть уменьшено до следующего. Модифицированный код может наконец получить 100 баллов.
#include<iostream>
#include<map>
using namespace std;
int main(){
long long n,m,k,ti,ci,t;
map<long long,long long,greater<>>field;
cin>>n>>m>>k;
while(n--){
cin>>ti>>ci;
field[ti]+=ci;
}
for(auto it=field.begin();it!=field.end();it++){
t=it->first;
if(it== prev(field.end())){
while(m>=it->second){
t--;
m-=it->second;
}
break;
}
auto next=it;
next++;
long long cost=it->second*(it->first-next->first);
if(m<cost){
while(m>=it->second){
t--;
m-=it->second;
}
break;
}
m-=cost;
next->second+=it->second;
}
t=t>=k?t:k;
cout<<t;
}