加载中...

枚举几何

找坐位https://ac.nowcoder.com/acm/contest/33186/C

需要注意 因为是射线而且起点固定 所以每一行只有最前面的那一个位置的斜率是符合要求的 可使用单指针的枚举 计算两个顶点开始 每一行不被射线射到的位置向下取整即可

#include <bits/stdc++.h>
#define ll long long
 
using namespace std;
 
int X[200007], Y[200007], Xrow[200007], Xgd0[200007], Xgdm[200007];
 
int main() {
    std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    int n, m, k, q;
    cin >> n >> m >> k >> q;
    for (int i = 1;i <= k;i++) cin >> X[i] >> Y[i];
    while (q--) {
        int id;
        cin >> id;
        cin >> X[id] >> Y[id];
        for (int y = 1;y <= m;y++) Xrow[y] = n + 1;
        for (int i = 1;i <= k;i++) Xrow[Y[i]] = min(Xrow[Y[i]], X[i]);///更新某行最靠前的人
        double k = 0;
        for (int y = 1;y <= m;y++) {
            k = max(k, 1.0 * (y - 1) / Xrow[y]);///更新(0,1)射线最大斜率
            if (k == 0) Xgd0[y] = Xrow[y] - 1;///斜率为0
            else Xgd0[y] = 1.0 * (y - 1) / k - 1e-9;///(x,x+1] = x,最大斜率与第y行交点(可能超过n)
        }
        k = 0;
        for (int y = m;y >= 1;y--) {
            k = min(k, 1.0 * (y - m) / Xrow[y]);///更新(0,m)射线最小斜率
            if (k == 0) Xgdm[y] = Xrow[y] - 1;
            else Xgdm[y] = 1.0 * (y - m) / k - 1e-9;
        }
        ll ans = 0;
        for (int y = 1;y <= m;y++) ans += min({ n,Xgd0[y],Xgdm[y] });
        cout << ans << '\n';
    }
    return 0;
}
posted @ 2022-08-18 14:38  liang302  阅读(57)  评论(0编辑  收藏  举报