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';
}

猜你喜欢

转载自www.cnblogs.com/Xray-luogu/p/11923247.html
今日推荐