其他分享
首页 > 其他分享> > 补题记录:E. Correct Placement

补题记录:E. Correct Placement

作者:互联网

补题记录:E. Correct Placement
学到了新的搜索技巧
E. Correct Placement

题意:给你一个矩形纸片,有h, w两个参数,当且仅当\(h_i < h_j \&\& w_i < w_j\)或者\(h_i < w_j \&\& w_i < h_j\),两者满足其一,则称纸片i可以放到j上,对于给定的每张纸片,输出可以放在其上面的序号,如果没有就输出-1
方法:排序
一开始我们很容易想到二分这个方法,我一开始用的是先保证一张纸片的\(h < w\)然后对h进行二分搜索,输出h相同的里面w最小的一个即可。后来wa了一遍找到了反例,还是采用了提交的代码里大多数人用的方法。
我们将所有的h和w进行排序,其中一个升序一个降序。由于找到一个满足的即可,于是我们排序完之后,遍历数组,h已经是从小到大的了,只要看w满不满足目前我们找到的w最小值,因为我们之前找到的w中,h一定是比当前的要小的,所以如果满足w > minw的话说明一定满足,记录答案即可,具体看代码

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
typedef pair<LL,LL> PLL;
const int INF = 0x3f3f3f3f, N = 1e5 + 10;
const int MOD = 1e9 + 7;
inline int lc(int u) {return u << 1;}
inline int rc(int u) {return u << 1 | 1;}
inline int lowbit(int x) {return x & (-x);}
struct node {
    int h, w, idx;
    bool operator < (const node &B) const {
        if (h != B.h) return h < B.h;
        return w < B.w;
    }
} a[N];
inline void solve() {
    int n; cin >> n;
    vector<node> p(n * 2);
    for (int i = 0; i < n; i ++ ) {
        int h, w; cin >> h >> w;
        p[i] = {h, -w, i + 1};
        p[i + n] = {w, -h, i + 1};
    }
    sort(p.begin(), p.end());
    vector<int> res(n + 1, -1);
    int mnw = 2e9, id = -1;
    for (auto &ite : p) {
        int h = ite.h, w = -ite.w, idx = ite.idx;
        if (w > mnw) res[idx] = id;
        else if (w < mnw){
            mnw = w;
            id = idx;
        }
    }
    for (int i = 1; i <= n; i ++ ) cout << res[i] << ' ';
    cout << endl;
}
int main() {
    ios::sync_with_stdio(false), cin.tie(nullptr);
    int t; cin >> t;
    while (t -- )
        solve();
    return 0;
}

标签:typedef,Placement,idx,int,ite,纸片,mnw,补题,Correct
来源: https://www.cnblogs.com/JYF-AC/p/14764079.html