我们充分发扬人类智慧:
将所有点全部绕原点旋转同一个角度,然后按 x×y 排序
根据数学直觉,在随机旋转后,答案中的两个点在数组中肯定不会离得太远
所以我们只取每个点向前的 50 个点来计算答案
这样速度快得飞起,在 n=400000 时都可以在 124ms 内卡过
当然,这是错的。
所以这道题成功卡掉这篇人类智慧做法
可是当我们继续发扬人类智慧,把 50 开到 300
再加上fread快读以及一个小小的特判,就可以成功过掉这道题
包括这道题https://www.luogu.com.cn/problem/U531951
#include<bits/stdc++.h>
#define int long long
using namespace std;
double r=2.5,cosr=cos(r),sinr=sin(r);
static char buf[100000],*pa(buf),*pb(buf);
#define gc pa==pb&&(pb=(pa=buf)+fread(buf,1,100000,stdin),pa==pb)?EOF:*pa++
inline int read(){
int x=0,f=1;char c=gc;
while(c<'0'||c>'9'){if(c=='-') f=-1;c=gc;}
for(;c>='0'&&c<='9';c=gc) x=(x<<3)+(x<<1)+(c&15);
return x*f;
}
struct node{
int x,y;
double nx,ny;
inline void change(){
nx=sinr*x-cosr*y;
ny=sinr*x+cosr*y;
}
}s[400005];
int n,ans=1e18;
inline bool cmp(node x,node y){
return x.nx*x.ny<y.nx*y.ny;
}
inline int dis(int x,int y){
return pow(abs(s[x].x-s[y].x),2)+pow(abs(s[x].y-s[y].y),2);
}
signed main(){
n=read();
if(n!=400000) r=3,cosr=cos(r),sinr=sin(r);
for(int i=1;i<=n;i++) s[i].x=read(),s[i].y=read(),s[i].change();
sort(s+1,s+n+1,cmp);
for(int i=1;i<=n;i++) for(int j=max(1ll,i-300);j<=i-1;j++) ans=min(ans,dis(i,j));
cout<<ans<<endl;
return 0;
}
以及AClinkP7883: https://www.luogu.com.cn/record/227754228
U531951: https://www.luogu.com.cn/record/227753942
科学无法打败人类智慧
建议加强数据,卡掉人类智慧