L2-054 三点共线

L2-054 三点共线

加详细数据点分析

题解

先把坐标为0,1,2的分开存入,再进行一个去重操作,然后双重for循环去找匹配的第三个数。

这里关于怎么找第三个数简单提一下,共线斜率相同则y1−y0y_1 - y_0y1y0 = y2−y1y_2 - y_1y2y1 可以求出目标y2y_2y2

到这里我最初想的是用unordered set去存所有的y2y_2y2方便查找是否存在目标但是数据3,5,7一直过不了。所以这道题在这里卡你,很恶心。

然后就发现这里数据是1e6,直接开一个数组实现O(1)查询。

最后是按照要求对答案排序输出

详细数据点分析

纯暴力,仅能过0,1,2三个数据点

加去重暴力能过数据4。数据3,5,7卡哈希。

ac code

#include<bits/stdc++.h>
typedef long long LL;
using namespace std;
const int N = 3e6 + 10;
int t,n;
class node{
	public:
		int a,b,c;
		bool operator<(const node& p) const{
			if(this->b != p.b){
				return this->b < p.b;
			}
			if(this->a != p.a){
				return this->a < p.a;
			}
			return this->c < p.c;
		}
};
vector<int>v0,v1,v2;
int f[N];
vector<node>ans;
void solve()
{
	cin >> n;
	for(int i = 1;i <= n;++ i)
	{
		int tmp_x,tmp_y;
		cin >> tmp_x >> tmp_y;
		if(tmp_y == 0)v0.push_back(tmp_x);
		if(tmp_y == 1)v1.push_back(tmp_x);
		if(tmp_y == 2)v2.push_back(tmp_x);
	}
	sort(v0.begin(),v0.end() );
	v0.erase(unique(v0.begin(),v0.end()),v0.end() );
	sort(v1.begin(),v1.end() );
	v1.erase(unique(v1.begin(),v1.end()),v1.end() );
	sort(v2.begin(),v2.end() );
	v2.erase(unique(v2.begin(),v2.end()),v2.end() );
	int k = 1000100;
	for(auto i : v2)
	{
		f[i + k] = 1;
	}
	if(v0.size() <= v1.size()){
		for(auto i : v0)
		{
			for(auto j : v1)
			{
				int tmp = j - i + j;
				if(abs(tmp) > k)continue;
				if(f[tmp + k]){
					ans.push_back({i,j,tmp});
				}
			}
		}		
	}else {
		for(auto j : v1){
			for(auto i : v0){
				int tmp = j + j - i;
				if(abs(tmp) > k)continue;
				if(f[tmp + k]){
					ans.push_back({i,j,tmp});
				}				
			}
		}
	}

	if(ans.empty()){
		cout << "-1";
		return;
	}
	sort(ans.begin(),ans.end() );
	for(auto i : ans)
	{
		cout << "[" << i.a << ", 0] [" << i.b << ", 1] [" << i.c << ", 2]\n";
	}
}
int main ()
{
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	//cin >> t;
	t = 1;
	while(t --)
	{
		solve();
	}
	






	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值