【问题标题】:Competitive programming problem I am stuck in我陷入的竞争性编程问题
【发布时间】:2020-10-10 10:00:16
【问题描述】:

所以有一个点列表 (x1,y1,z1),(x2,y2,z2),...(xn,yn,zn)。

您可以对任意数量的这些点执行操作 O。

操作 O 导致 (x,y,z)= (max(x1,x2,...xn),max(y1,y2,...yn),max(z1,z2,...zn ))。

给定(x,y,z),你需要判断是否可以对列表中的一些点进行O操作得到(x,y,z)的结果。

例如:给你点 (1,2,1),(3,1,4),(5,2,1)。 能不能进行O运算得到1) (3,2,1) 2) (1,1,1)

第一行包含 n 和 q,即点数和 no。查询次数

接下来的 n 行包含空间分隔的 n 个点

接下来的 q 行包含 q 个点,它们是查询

1<=q<=10^5
1<=n<=10^5

x,y,z 是整数

输入:

2 2
1 3 5
5 3 1
5 3 5
3 3 3

预期输出:

YES
NO

我的逻辑:

for (int i = 0; i < q; i++)
{
    cin>>x>>y>>z;
    for (int j = 0; j < n; j++)
    {

        if(arr[j][0]==x && arr[j][1]<=y && arr[j][2]<=z)
            first=1;
        if(arr[j][0]<=x && arr[j][1]==y && arr[j][2]<=z)
            second=1;
        if(arr[j][0]<=x && arr[j][1]<=y && arr[j][2]==z)
            third=1;
        if(first+second+third==3)
            break;
    }
    if(first+second+third==3)
        cout<<"YES\n";
    else
    {
        cout<<"NO\n";
    }
    first=0;
    second=0;
    third=0;
}

注意:这里 arr[][] 包含给定的坐标。 对于查询 q 中的每个 x y z,我正在执行此操作。

很少有测试用例失败,给我一个运行时错误(超出时间限制)。有没有更好的方法来做到这一点。

【问题讨论】:

  • 请不要发送不相关的语言标签。
  • 抱歉,我是网站新手,我已经删除了 2 个语言标签
  • 请提供minimal reproducible example 输入、预期输出和实际输出
  • 我已经添加了输入和预期的输出。希望现在很清楚
  • @roccok123 你能说出qn 和坐标xyz 的限制(范围)吗?它们都是整数吗?

标签: c++ arrays performance


【解决方案1】:

您的解决方案是正确的,但速度很慢,O(q * n) 的复杂性最多为 10^10,太多了。

我已经使用排序和合并搜索解决了您的任务,它具有O(n log n + q log q) 的复杂性。

算法如下:

对于(x, y, z)(y, x, z)(z, x, y) 三种情况中的每一种,表示为坐标(i0, i1, i2),我们接下来进行:

  1. 按元组(i0, i1, i2)对所有点和查询进行排序。
  2. 在每个相等的坐标i0 中计算i2 的累积最小值。
  3. 下一步合并排序的点和查询:对于每个查询范围和具有相等i0i1 的点,取最右边的最小i2。如果点的最小i2 大于查询的i2,则此查询的答案是NO,否则可能是YES(可能意味着对于(x, y, z)/ 的所有3 个排序,它应该是YES (y, x, z)/(z, x, y))。

上面的算法基本上和你的算法做同样的事情,它找到等于xyz的点,这样其他两个坐标就不会更大。但是通过合并两个排序数组的快速算法来实现。因此,合并本身只需要O(q + n) 时间,而整个算法时间主要由需要O(q log q + n log n) 时间的排序算法支配。

Try it online!

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

using namespace std;

typedef int CoordT;
typedef tuple<CoordT, CoordT, CoordT> CoordsT;
typedef vector<CoordsT> CoordsVecT;

template <size_t i0, size_t i1, size_t i2>
static void Solve(CoordsVecT const & ps, CoordsVecT const & qs, vector<bool> & yes) {
    auto Prep = [&](auto & s, auto const & o){
        s.clear();
        s.reserve(o.size());
        for (size_t i = 0; i < o.size(); ++i)
            s.push_back(make_tuple(get<0>(o[i]), get<1>(o[i]), get<2>(o[i]), i));
            
        sort(s.begin(), s.end(), [](auto const & l, auto const & r) -> bool {
            return get<i0>(l) < get<i0>(r) || get<i0>(l) == get<i0>(r) && (
                get<i1>(l) < get<i1>(r) || get<i1>(l) == get<i1>(r) &&
                    get<i2>(l) < get<i2>(r)
            );
        });
    };
    vector< tuple<CoordT, CoordT, CoordT, size_t> > sps, sqs;
    Prep(sps, ps);
    Prep(sqs, qs);
    vector<CoordT> mins2(sps.size());
    CoordT cmin2 = 0;
    for (size_t i = 0; i < sps.size(); ++i) {
        if (i == 0 || get<i0>(sps[i - 1]) != get<i0>(sps[i]))
            cmin2 = get<i2>(sps[i]);
        cmin2 = std::min(cmin2, get<i2>(sps[i]));
        mins2[i] = cmin2;
    }
    for (size_t iq = 0, ip = 0; iq < sqs.size(); ++iq) {
        auto & cyes = yes[get<3>(sqs[iq])];
        if (!cyes)
            continue;
        while (ip < sps.size() && get<0>(sps[ip]) < get<0>(sqs[iq]))
            ++ip;
        if (ip >= sps.size() || get<0>(sps[ip]) != get<0>(sqs[iq])) {
            cyes = false;
            continue;
        }
        while (ip + 1 < sps.size() && get<0>(sps[ip + 1]) == get<0>(sqs[iq]) && get<1>(sps[ip + 1]) <= get<1>(sqs[iq]))
            ++ip;
        if (ip >= sps.size() || get<1>(sps[ip]) > get<1>(sqs[iq]) || mins2[ip] > get<2>(sqs[iq])) {
            cyes = false;
            continue;
        }
    }
}

int main() {
    size_t n = 0, q = 0;
    cin >> n >> q;
    auto Input = [](CoordsVecT & v, size_t cnt) {
        v.reserve(v.size() + cnt);
        for (size_t i = 0; i < cnt; ++i) {
            CoordT x, y, z;
            cin >> x >> y >> z;
            v.push_back(make_tuple(x, y, z));
        }
    };
    CoordsVecT ps, qs;
    Input(ps, n);
    Input(qs, q);
    vector<bool> yes(qs.size(), true);
    Solve<0, 1, 2>(ps, qs, yes);
    Solve<1, 0, 2>(ps, qs, yes);
    Solve<2, 0, 1>(ps, qs, yes);
    for (size_t i = 0; i < qs.size(); ++i)
        cout << (yes[i] ? "YES" : "NO") << endl;
    return 0;
}

输入:

2 2
1 3 5
5 3 1
5 3 5
3 3 3

输出:

YES
NO

【讨论】:

    猜你喜欢
    • 2023-03-08
    • 1970-01-01
    • 2022-11-18
    • 2021-09-15
    • 2021-01-07
    • 2021-01-05
    • 2012-04-02
    • 2019-04-25
    • 1970-01-01
    相关资源
    最近更新 更多