ABC213

C

题意:给你一个网格,宽为W,高为H,然后输入N个坐标,对于(i = 1, 2,...,N),第i个坐标处填i,重复下面两种操作:

  1. 删除空行
  2. 删除空列

问最终每一个数字的位置在哪

方法: 排序去重+二分,由于(1≤H,W≤10^9),所以不能模拟来做,对于每一个数字只需要关心这个数字上面有一个非空行cntx,左边有几个非空列cnty,最终的位置就是(cntx + 1, cnty + 1)

#include<iostream>
#include<vector>
#include<algorithm>

using namespace std;

int h, w, n;
vector<pair<int, int>> p;
vector<int> x, y;

int find(int x, vector<int> &v){
    int l = 0, r = (int) v.size() - 1;
    while(l < r){
        int mid = l + r + 1 >> 1;
        if(v[mid] <= x) l = mid;
        else r = mid - 1;
    }
    
    if(v[l] <= x) return l + 1;
    return 0;
}

int main(){
    cin >> h >> w >> n;
    for(int i = 0; i < n; i ++){
        int a, b;
        cin >> a >> b;
        p.push_back({a, b});
        x.push_back(a);
        y.push_back(b);
    }
    
    sort(x.begin(), x.end());
    sort(y.begin(), y.end());
    
    x.resize(unique(x.begin(), x.end()) - x.begin());
    y.resize(unique(y.begin(), y.end()) - y.begin());
    
    for(int i = 0; i < n; i ++){
        int cntx = find(p[i].first - 1, x), cnty = find(p[i].second - 1, y);
        cout << cntx + 1 << ' ' << cnty + 1 << endl;
    }
}

D

题意:给你一个树,打印从1出发把所有顶点访问一遍再回到1的递归过程,注意再访问过程中优先选择序号小的顶点

#include<iostream>
#include<vector>
#include<algorithm>

using namespace std;

const int N = 2e5 + 10;

int n;
vector<int> h[N];
vector<int> ans;

void dfs(int u, int pre){
    for(int i = 0; i < h[u].size(); i ++){
        int j = h[u][i];
        if(j != pre){
            ans.push_back(j);
            dfs(j, u);
            ans.push_back(u);
        }
    }
    
    if(u == 1) return;
}

int main(){
    cin >> n;
    for(int i = 0; i < n - 1; i ++){
        int a, b;
        cin >> a >> b;
        h[a].push_back(b);
        h[b].push_back(a);
    }
    
    for(int i = 1; i < N; i ++) sort(h[i].begin(), h[i].end());
    
    ans.push_back(1);
    dfs(1, -1);
    
    for(auto t : ans) cout << t << ' ';
}
原文地址:https://www.cnblogs.com/tomori/p/15441423.html