L2-054 三点共线
加详细数据点分析
题解
先把坐标为0,1,2的分开存入,再进行一个去重操作,然后双重for循环去找匹配的第三个数。
这里关于怎么找第三个数简单提一下,共线斜率相同则y1−y0y_1 - y_0y1−y0 = y2−y1y_2 - y_1y2−y1 可以求出目标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;
}