如何解决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
坐标图像:
通过一个简单的循环解决了以下问题,但是当输入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;
}
在这种情况下,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,共有三种可能的配置:
- A使B不可见
- B使A不可见
- 以上都不是
std::sort
不需要strict weak ordering之间的点之间的“使不可见”关系,因此使用实现该关系的比较函数调用std::sort
是不确定的。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。