这似乎是本人第一次写文章。
本人是一个纯纯算法小白,通信工程专业,只不过最近在准备蓝桥杯而已。。。
多记录一下自己学到的知识对自己的提高总归是有好处的 吧
本题解原链接: (10条消息) (牛客)两条斜线_悠唯的博客-CSDN博客_牛客斜线
我只是单纯的体会一遍,对本题的题解没有任何帮助。
当然有巨巨有更好的算法,欢迎狠狠拷打我,我在不断进步捏
不废话了呜呜呜
首先就是看到直线斜率真的一定要往解析式去想阿,对做题真的大有帮助。
我最开始想的是,找一个点,然后往四面八方暴力
后来一想,且不提这方法有多麻烦,这两条直线压根可能不会香蕉,属于是题没读明白了
用解析式真的方便,一个b就能代表一条直线
这道题对我来说最重要的知识应该是这个map的使用,实际上应该就是哈希吗
只不过我一直都不太明白怎么写,怎么查找,这下会了
map<int,int>mb1,mb2; //保存各b1 b2 有多少点经过,每遍历一个点计算出b 然后
//以b为key ,给对应value+1
for(int i = 0;i<n;i++)
{
int b1 = y[i] - x[i];
int b2 = y[i] + x[i];
mb1[b1]++;mb2[b2]++;//遍历到一个点,它对应的b在map里对应的量都要加1
if(mb1[b1]>m1)
{
v1.clear();
v1.push_back(b1);
m1 = mb1[b1];
}
else if(mb1[b1]==m1)v1.push_back(b1);
这两个map就好像大筐一样什么都收,因为不同的点可能对应不同的b1,b2,
遍历每个点时,得到的b1就会被mb1当作key吸收进去,成为map里的一个元素,他的值就是遍历至此所有对应这个b值的点的个数,也就是在这条线上的个数,因为每个b1/b2都对应一条线嘛
总而言之,map里的元素就是每条线,它对应的值就是这个线上点的个数(卧槽我说明白了)
这个vector应该是一种剪枝的手法吧,同样m1,m2也是为这两个vector服务的
想象一下没有这些vector会怎么样
我们遍历所有点之后map已经存好他想要的数据了,
之后只需要遍历两个map,然后看他们对应的点个数之和哪个大就好了
还是满浪费时间的哦
vector用来记录那条(或那几条)线有着最多的点,也会不断刷新
因此最后加和的时候只需要从这两个vec里面找就好,而不需要从庞大的map里面找了
m1,m2是记录某条线上的点数的最大值,会不断刷新
一定要记得,这两条线是分立的,他们对彼此都没有什么影响。
因此只需要分开记最大值,然后再加起来,就这么简单就行,别想太多(对自己说)
如果m1,m2被刷新了,那vector里面原来的线就没用了就给他清掉,再加入新的
有更多点的线
大概就这么多
最后再放一下代码啦
#include<bits/stdc++.h>
using namespace std;
map<int,int>mb1,mb2; //保存各b1 b2 有多少点经过,每遍历一个点计算出b 然后
//以b为key ,给对应value+1
vector<int >v1;
vector<int >v2;
int x[1005];
int y[1005];
int n;
//斜率为1: y = x + b1; ==> b1 = y-x;
//斜率为-1: y = -x+ b2; ==> b2 = y+x;
int sum(int b1,int b2) //b1 b2各代表一条线,计算这两条直线会经过点的个数和
{
int cnt = 0;
for(int i =0;i<n;i++)
if(y[i]-x[i]==b1||y[i]+x[i]==b2)cnt++;
return cnt;
}
int main()
{
cin>>n;
for(int i = 0;i<n;i++)
scanf("%d",&x[i]);
for(int i = 0;i<n;i++)
scanf("%d",&y[i]);
int m1 = 0,m2 = 0; //在b1/b2线上点的个数
for(int i = 0;i<n;i++)
{
int b1 = y[i] - x[i];
int b2 = y[i] + x[i];
mb1[b1]++;mb2[b2]++;//遍历到一个点,它对应的b在map里对应的量都要加1
if(mb1[b1]>m1)
{
v1.clear();
v1.push_back(b1);
m1 = mb1[b1];
}
else if(mb1[b1]==m1)v1.push_back(b1);
if(mb2[b2]>m2)
{
v2.clear();
v2.push_back(b2);
m2 = mb2[b2];
}
else if(mb2[b2]==m2)v2.push_back(b2);
}
int res = 0;
for(int i = 0;i<v1.size();i++)
for(int j = 0;j<v2.size();j++)
{
res = max(res,sum(v1[i],v2[j]));
}
cout<<res;
}