Meeting

2020-07-06 个人赛1 E:Meetings


题面:

样例:

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <map>
#include <queue>
#include <vector>
#include <cmath>
#include <set>
using namespace std;
typedef long long ll;
const int MAXN = 2e6 + 10;
const int NUM = 1e5 + 50;

template <class T>
inline bool scan_d(T& ret) {
    char c; int sgn;
    if (c = getchar(), c == EOF) return 0; //EOF
    while (c != '-' && (c<'0' || c>'9')) c = getchar();
    sgn = (c == '-') ? -1 : 1;
    ret = (c == '-') ? 0 : (c - '0');
    while (c = getchar(), c >= '0' && c <= '9') ret = ret * 10 + (c - '0');
    ret *= sgn;
    return 1;
}

struct node
{
    int w, x, d;///重量、坐标、方向
}a[50010];
int n, L;///n头牛 L区间
bool cmp(node a, node b)
{
    return a.x < b.x;///按照坐标排序
}
int tot_weight;
///经过t秒后 判断到达奶牛重量之和是否大于等于一半
bool judge(int t)
{
    int weight = 0;
    int left = 1, right = n;
    for (int i = 1; i <= n; i++)
    {
        ///计算第i头牛t秒的坐标(穿越)
        int now_x = a[i].x + t * a[i].d;
        if (now_x >= L)weight += a[right].w, right--;
        if (now_x <= 0)weight += a[left].w, left++;
    }
    if (weight * 2 >= tot_weight)
        return true;
    else
        return false;
}

///查找数组a中,值属于[L, R]的数字个数
int f1(vector<int> & y, int L, int R)
{
    int l = lower_bound(y.begin(), y.end(), L) - y.begin();
    int r = lower_bound(y.begin(), y.end(), R) - y.begin();
    if (r < y.size() && y[r] == R)r++;
    return r - l;
}
int f2(vector<int> & x, int L, int R)
{
    int l = lower_bound(x.begin(), x.end(), L) - x.begin();
    int r = lower_bound(x.begin(), x.end(), R) - x.begin();
    if (r < x.size() && x[r] == R)r++;
    return r - l;
}
int main()
{
    vector<int>x, y;
    cin >> n >> L;
    for (int i = 1; i <= n; i++)
    {
        cin >> a[i].w >> a[i].x >> a[i].d;
        tot_weight += a[i].w;
        if (a[i].d == 1)x.push_back(a[i].x);///存储所有方向朝右的位置
        else y.push_back(a[i].x);
    }
    sort(x.begin(), x.end());///greater<int>()
    sort(y.begin(), y.end());
    sort(a + 1, a + 1 + n, cmp);
    int l = 1, r = L, T;
    while (l <= r)
    {
        int mid = (l + r) / 2;
        if (judge(mid))///到达奶牛重量之和 大于等于 一半
        {
            T = mid;
            r = mid - 1;
        }
        else
        {
            l = mid + 1;
        }
    }
    ll ans = 0;
    for (int i = 1; i <= n; i++)
    {
        if (a[i].d == 1)///找往左走的牛中坐标处于[a[i].x + 1, a[i].x + 2 * T]的数量
            ans += f1(y, a[i].x + 1, a[i].x + 2 * T);
        else///找往右走的牛中坐标处于[a[i].x - 2 * T, a[i].x - 1]的数量
            ans += f2(x, a[i].x - 2 * T, a[i].x - 1);
    }
    cout << ans / 2 << endl;
    return 0;
}
原文地址:https://www.cnblogs.com/ZJNU-huyh/p/13281080.html