CSP-J 2019 公交換乘 題解

這就是我在遊記裏講的那個 \(O(45n \log n)\) 的垃圾寫法。不知道爲什麼我對這題最直觀的寫法就是這個。

思路就是如果是地鐵,就放到一個數組中(代碼中用結構體實現),如果是公交車,就放到 map 裏(那個 \(\log\) 就是這麼來的)。
然後再寫一個二重循環,反正枚舉就是了。
最後把 map 掃一遍。

我考場上慫,寫了 \(price_i\) 都相等的部分分。

下面是考場代碼,寫的很亂:

#include <bits/stdc++.h>
using namespace std;
const int maxN=100005;
int n;
struct Node {
    int price;
    int t;
}a[maxN];
priority_queue<int,vector<int>,greater<int> > q;
map<int,int> mp;
map<int,int> PRICE;
int ans,tot;
void rd(int&);
int OP[maxN],X[maxN],Y[maxN];
bool check();
void spwork();
int main() {
    freopen("transfer.in","r",stdin);
    freopen("transfer.out","w",stdout);
    rd(n);
    //if (n<=1000)
    //  task1::work();
    for (register int i=1;i<=n;i++) {
        //int op,x,y;
        rd(OP[i]),rd(X[i]),rd(Y[i]);}if (check()){spwork();return 0;}
        for (register int i=1;i<=n;i++) {
        if (!OP[i]) {
            a[++tot].price=X[i];
            a[tot].t=Y[i];
            ans+=X[i];
        }
        if (OP[i]==1) {
            mp[Y[i]]=1;
            PRICE[Y[i]]=X[i];
        }
    }
    //cout<<"tot="<<tot<<'\n';
    for (register int i=1;i<=tot;i++)
        for (register int j=1;j<=45;j++) {
            if (!mp[a[i].t+j]||PRICE[a[i].t+j]>a[i].price)
                continue;
            mp[a[i].t+j]=0;
            //cout<<"a[i].t+j="<<a[i].t+j<<'\n';
            break;
        }
    map<int,int> :: iterator it;
    for (it=mp.begin();it!=mp.end();it++) {
        if (it->second)
            ans+=PRICE[it->first];
        //cout<<"it->second="<<it->second<<'\n';
    }
    //for (map<int,int> :: iterator it=PRICE.begin();it!=PRICE.end();it++)
    //cout<<"it->first="<<it->first<<" it->second="<<it->second<<'\n'; PRICE ok
    //for (map<int,int> :: iterator it=mp.begin();it!=mp.end();it++)
    //  cout<<"it->first="<<it->first<<" it->second="<<it->second<<'\n';
    cout<<ans<<'\n';
    //cout<<clock();
    return 0;
}
void rd(int& x) {
    x=0;
    char ch=getchar();
    while (!isdigit(ch))
        ch=getchar();
    while (isdigit(ch)) {
        x=x*10+ch-48;
        ch=getchar();
    }
}
bool check() {
    for (int i=2;i<=n;i++)
        if (X[i]!=X[i-1])
            return false;
    return true;
}
void spwork() {
    int ans=0;
    for (int i=1;i<=n;i++) {
        if (!OP[i])
            q.push(Y[i]),ans+=X[i];
        if (OP[i]==1) {
            bool flag=true;
            while (!q.empty()) {
                if (Y[i]-q.top()>45)
                    q.pop();
                else {
                    q.pop();
                    flag=false;
                    break;
                }
            }
            if (flag) {
                ans+=X[i];
            }
        }
    }
    cout<<ans<<'\n';
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章