这题我很笨,很暴力,数据大一点可能就被卡了

我 很 暴 力 的 枚 举 两 个 点 确 定 斜 率 我很暴力的枚举两个点确定斜率

Ⅰ . 然 后 这 两 个 点 确 定 一 条 直 线 , 那 么 筛 掉 所 有 在 这 条 直 线 的 点 Ⅰ.然后这两个点确定一条直线,那么筛掉所有在这条直线的点 .线,线

Ⅱ . 其 余 所 有 没 被 筛 掉 的 点 在 另 一 条 平 行 线 上 , 判 断 斜 率 是 否 相 等 就 行 Ⅱ.其余所有没被筛掉的点在另一条平行线上,判断斜率是否相等就行 .线,

这 样 是 n 3 的 , 可 以 用 m a p 标 记 每 次 确 定 的 斜 率 , 遇 到 相 同 的 就 停 止 这样是n^3的,可以用map标记每次确定的斜率,遇到相同的就停止 n3,map,

很 暴 力 对 吧 ? 但 是 能 过 。 不 过 有 更 好 的 做 法 \color{Red}很暴力对吧?但是能过。不过有更好的做法 ?

任意取三个点,两两构成直线有3种可能的斜率

如果答案存在,那么至少有一个是正确的斜率

代 码 如 下 代码如下

#include <bits/stdc++.h>
using namespace std;
const double eps = 1e-5;
const int maxn=2e5+10;
int n,a[maxn],ans;
double ji(int q,int w){
	return (a[w]-a[q])*1.0/(w*1.0-q*1.0);
}
map<double,int>m;
void isok(int i,int j)
{
	int num=0,flag=1;
	double xie=ji(i,j);
	for(int q=1;q<=n;q++)
	{
		if(q==i||q==j)	continue;
		if( abs(ji(i,q) - xie)<eps )	continue;
		else if(num==0)	num=q;
		else
		{
			if( abs(ji(q,num) - xie)<eps)	continue;
			else	flag=0;
		}
	}
	if(flag&&num)	ans=1;
}
int main()
{
	cin >> n;
	for(int i=1;i<=n;i++)	cin >> a[i];
	isok(1,2);isok(2,3);isok(1,3);
	if( ans )	cout<<"Yes";
	else	cout<<"No";
}

暴力枚举代码

#include <bits/stdc++.h>
using namespace std;
const double eps = 1e-5;
const int maxn=2e5+10;
int n,a[maxn],ans;
double ji(int q,int w){
	return (a[w]-a[q])*1.0/(w*1.0-q*1.0);
}
map<double,int>m;
int main()
{
	cin >> n;
	for(int i=1;i<=n;i++)	cin >> a[i];
	int k=1;
	for(int i=1;i<=n;i++)//枚举起点
	{
		for(int j=i+1;j<=n;j++)
		{
			//由i和j点确定的这条直线斜率 
			double xie = ji(i,j);
			if(m[xie])	continue;
			m[xie]=1;
			int num=0,flag=1;
			for(int q=1;q<=n;q++)
			{
				if(q==i||q==j)	continue;
				if(flag==0)	break;
				if( abs(ji(i,q) - xie)<eps )	continue;
				else if(num==0)	num=q;
				else
				{
					if( abs(ji(q,num) - xie)<eps)	continue;
					else	flag=0;
				}
			}
			if(flag&&num)	ans=1;
		}
	} 
	if( ans )	cout<<"Yes";
	else	cout<<"No";
}