CSP 202305-2 План мелиорации земель

 

Обычный метод прямого использования цикла для поиска наибольшего количества дней может принести только 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;
}

Supongo que te gusta

Origin blog.csdn.net/weixin_62264287/article/details/132719184
Recomendado
Clasificación