这题我很笨,很暴力,数据大一点可能就被卡了
我 很 暴 力 的 枚 举 两 个 点 确 定 斜 率 我很暴力的枚举两个点确定斜率 我很暴力的枚举两个点确定斜率
Ⅰ . 然 后 这 两 个 点 确 定 一 条 直 线 , 那 么 筛 掉 所 有 在 这 条 直 线 的 点 Ⅰ.然后这两个点确定一条直线,那么筛掉所有在这条直线的点 Ⅰ.然后这两个点确定一条直线,那么筛掉所有在这条直线的点
Ⅱ . 其 余 所 有 没 被 筛 掉 的 点 在 另 一 条 平 行 线 上 , 判 断 斜 率 是 否 相 等 就 行 Ⅱ.其余所有没被筛掉的点在另一条平行线上,判断斜率是否相等就行 Ⅱ.其余所有没被筛掉的点在另一条平行线上,判断斜率是否相等就行
这 样 是 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";
}