如果给你一组点,你需要找到可以用这些点制作的直角三角形的数量(两边平行于x和y轴),这将是一种有效的方法。做到了吗?
我想出了一些代码,用来检查每个给定点是否有一条线(除了我摆脱的一些个别点)
这是我的代码:
#include <iostream>
#include <vector>
using namespace std;
int main() {
int n;
cin>>n;
vector<int> storex[100010];
vector<int> storey[100010];
vector< pair< int,int > > singlepoints;
vector<int> canstorex;
int pointsx[100010];
int pointsy[100010];
vector<int> canstorey;
for(int i=0;i<n;i++){
int x,y;
cin>>x>>y;
storex[x].push_back(y);
storey[y].push_back(x);
}
for(int i=0;i<100010;i++){
if(storex[i].size()>1){
/*if(storex[i].size() == 1){
singlepoints.push_back(make_pair(i,storex[i][0]));
}*/
canstorex.push_back(i);
pointsx[i] = storex[i].size();
}
if(storey[i].size()>1){
/*if(storey[i].size() == 1){
singlepoints.push_back(make_pair(storex[i][0],i));
}*/
canstorey.push_back(i);
pointsy[i] = storey[i].size();
}
}
int count = 0;
for(int i =0;i<canstorex.size();i++){
int temp = canstorex[i];
//std::cout<<storex[temp].size()<<endl;
for(int j =0;j<storex[temp].size();j++){
int tempcount = 0;
if(storey[storex[temp][j]].size()>1){
//std::cout<<pointsx[temp]<<endl;
tempcount+=(storey[storex[temp][j]].size()-1);
if(pointsx[temp]>2){
tempcount*= (pointsx[temp]-1);
}
if(pointsy[storex[temp][j]]>2){
tempcount*= (pointsy[storex[temp][j]]-1);
}
}
count +=tempcount;
}
}
std::cout<<count;
/*for(int i =0;i<canstorey.size();i++){
}*/
}
答案 0 :(得分:0)
假设你的点是整数,你只想要一边与x轴平行的三角形,另一边与y轴平行,第三边连接两边不是两边交点,那么我将在容器中的x上的数据和在另一个容器中的y上的数据进行排序。
对于第一个容器,我也会在x中匹配y个点。比较函子看起来像:
class CompareXY
{
bool operator()(const &Point lhs, const &Point rhs) const
{
return lhx.x != rhs.x ? lhs.x < rhs.x : lhs.y < rhs.y;
}
};
对于第二个容器,您将反转比较(class CompareYX
)。
然后你会遍历x。对于每个x至少有一个具有相同x的另一个点(你应该计算它们 - 见下文),我会计算具有相同y(但是不同的x)的点的数量。
您可以使用std::equal_range
查找给定y的范围,然后使用std::count_if
计算有效制作直角三角形的点数。
此时,您将上述两个计数步骤中的点数相乘,并将其与累积的三角形数量相加。
您已正确排序数据的事实允许您限制每个x或y的检查次数。
完成后,您可以根据数据进行额外的优化。你可能想要考虑的事情是:
std::equal_range
可以替换为std::lower_bound
吗?您可能尝试的一件事是最初进行更具侵略性的过滤。我不确定它是否会有所帮助。你必须衡量绩效。一个想法是:
在这种情况下,我可能会先进行组合(y然后x 或 x然后y)排序以避免额外排序。
顺便说一下,根据数据,性能可能会有很大差异。因此,用实际数据衡量性能以查看其效果可能是个好主意。在x或y坐标范围很大(比如说超过几千)时,您将拥有非常少的直角三角形,因此激烈的初始过滤可能有助于更快地减少数据大小,从而提高剩余步骤的性能。另一方面,如果数据在x和y坐标中被压缩,初始过滤将浪费时间,因为无论如何大多数数据都会被保留,因此无论如何都要重新检查。