C ++:在坐标平面中比较坐标的问题中,我不知道如何解决超时问题

如何解决C ++:在坐标平面中比较坐标的问题中,我不知道如何解决超时问题

最多输入100,000个坐标。仅输出对应于特定条件的坐标。如果存在比每个坐标更大的x值和y较小的坐标,则从输出列表中排除相应的坐标。

我的英语不好,所以我举一些例子。

[输入] 首先输入要输入的坐标数N。并输入坐标。

[输出] 与条件相对应的坐标编号以升序输出。

p2 is not correct p4 is correct

[input example]

6
1 3
6 6
7 3
8 2
8 6
2 1
[output example]

4
5
6

时间限制为500毫秒。

[timeout input example]

50000
1 1
1 2
1 3
... skip
1 49999
1 50000
[timeout output example]

1 1
1 2
1 3
... skip
1 49999
1 50000

坐标图像:

img

通过一个简单的循环解决了以下问题,但是当输入100,000个值时会发生超时。我不知道该使用哪种算法。

我还附上了我编写的C ++源代码。

我也尝试使用sort函数,但是当N的数量较小时,它可以正常工作;而当N的数量较大时,则无法正确比较。我想我无法正确编写比较功能。 因此,我尝试不使用sort编写源代码。

我经过两天的思考和纠正,但无法解决,因此寻求帮助。感谢您的阅读。

#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
int main() {
    int N;
    cin >> N;
    bool* visible = new bool[N];
    for (int i = 0; i < N; i++)visible[i] = true;
    
    vector<pair<int,pair<int,int>>> v;
    
    for (int i = 0; i < N; i++) {
        int a,b;
        cin >> a >> b;
        v.push_back(make_pair(i,make_pair(a,b)));
    }

    for (int i = 0; i < v.size(); i++) {
        if (visible[i] == false)
            continue;
        for (int j = 0; j < v.size(); j++) {
            if (visible[i] == true &&visible[j]==true && v[i].second.first < v[j].second.first && v[i].second.second > v[j].second.second) {
                visible[i] = false;
                break;
            }
            else if (visible[i] == true && visible[j] == true && v[i].second.first > v[j].second.first && v[i].second.second < v[j].second.second) {
                visible[j] = false;
                continue;
            }
        }
    }
    for (int i = 0; i < v.size(); i++) {
        if (visible[i] == true)
            cout << v[i].first + 1 << endl;
    }
    return 0;
}

[试图排序但失败的源代码]

#include <iostream>
#include <algorithm>
#include <vector>
#include <tuple>
using namespace std;
bool* visible;

int compare(pair<int,int>> n1,int>> n2) {
    pair<int,int> a = n1.second,b = n2.second;
    bool swap = false;
    if (a.first > b.first && a.second < b.second) { 
        visible[n2.first - 1] = false;
        swap = true;
    }
    else if (a.first < b.first && a.second > b.second) {
        visible[n1.first - 1] = false;
        //swap = true;
    }

    cout << "[" << n1.first << "]" << a.first << "," << a.second << " vb : " << visible[n1.first - 1] << " :\t[" << n2.first << "]" << b.first << "," << b.second << "vb : " << visible[n2.first - 1] << "\t";
    cout << "swap: " << swap << endl;
    return swap;
}
int main() {
    int N;
    cin >> N;
    visible = new bool[N];
    for (int i = 0; i < N; i++)visible[i] = true;
    vector<pair<int,int>>> v;

    for (int i = 0; i < N; i++) {
        int a,b;
        cin >> a >> b;
        v.push_back(make_pair(i+1,b)));
    }
    sort(v.begin(),v.end(),compare);
    for (int i = 0; i < v.size(); i++)
        cout << "p" << v[i].first << " : " << v[i].second.first << "," << v[i].second.second <<"\t"<< visible[v[i].first-1]<< endl;
    
    return 0;
}

enter image description here

在这种情况下,p4移至(4,2)。在这种情况下,p3,4,5,6成为正确答案。

解决方法

我不确定这是否适用于每个极端情况,但想法就在这里。我花了一些时间才将其确定下来,可能是因为问题描述并不清楚。基本上,您希望将可能找到另一个x较大且y较小的点标记为不可见,即在右下角具有另一个的点。

如果在x上对点进行排序,则只需要检查索引较大的点即可。

实际上,我们只对具有最小y的那个感兴趣,因为它将控制所有其他y。

该值只能在从右向左移动时减小,因此我们只需要跟踪最小值y。唯一的问题是如何处理具有相同x的点,因为它们可能在具有较高x的点之前具有较低的y,从而使有效点不可见。诀窍是确保从右向左浏览(从较高的索引到较低的索引),y会减小。因此,排序时,如果x相等,我们将对y进行排序。

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

int main() 
{
    struct point {
        int x,y;
        bool visible = true;
    };

    size_t N;
    std::cin >> N;
    std::vector<point> v(N);
    std::vector<size_t> idx(N);
    for (size_t i = 0; i < N; ++i) {
        auto& p = v[i];
        idx[i] = i;
        std::cin >> p.x >> p.y;
    }

    sort(idx.begin(),idx.end(),[&v](const size_t& a,const size_t& b) { 
        if (v[a].x == v[b].x)
            return v[a].y < v[b].y;
        return v[a].x < v[b].x; 
    });

    int miny = INT_MAX;
    for (size_t i = N; i-- > 0;) {
        auto& p = v[idx[i]];
        miny = std::min(miny,p.y);
        if (p.y > miny) {
            p.visible = false;
        }
    }

    for (size_t i = 0; i < N; ++i) {
        auto& p = v[i];
        if (p.visible) {
            std::cout << i + 1 << '\n';
        }
    }

    return 0;
}
,

我从您的代码中了解了两件事,所以我将列出两种解决方案:

I:这是修改后的“最长递增子序列”的基本示例。

首先让我们将坐标视为不同的东西,比如说,坐标(x,y)将成为高度(x)和宽度(y)的ractangle(考虑这就像我们制作带角的矩形(0 ,0)(x,0)(0,y)(x,y))。

如果我们需要“升序”点,则意味着它们的区域重叠。更正式地讲,如果我们需要的点列表是A(1),A(2),A(3),...,A(k),则对于范围1..k-1中的每个i,A( i).x

您可以使用this

找到最佳解决方案

注意:坐标应排序。以什么标准?好吧,只要排序该标准后出现最长的增长子序列,那是正确的。

II:这是找到凸包的基本示例。

多边形的凸包将是凸多边形(具有最多的节点),其坐标集包含在原始多边形的坐标集中。我建议阅读this。找到上半部分后,您可以按照上一个示例中的描述进行操作,尽管必须找到一个子字符串而不是一个子序列,这样会使复杂度为O(nlog + n)

希望这很有帮助

,

给出两个点A和B,共有三种可能的配置:

  1. A使B不可见
  2. B使A不可见
  3. 以上都不是

std::sort不需要strict weak ordering之间的点之间的“使不可见”关系,因此使用实现该关系的比较函数调用std::sort是不确定的。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 &lt;select id=&quot;xxx&quot;&gt; SELECT di.id, di.name, di.work_type, di.updated... &lt;where&gt; &lt;if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 &lt;property name=&quot;dynamic.classpath&quot; value=&quot;tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-