点
文件名newbarn.c/cpp/pas 时间限制1s 内存限制128M
题目描述
有N个二维坐标上的整数点(Xi,Yi)。现在请你选择一个不与N个点重合的整数点(X,Y)。最小化距离
输入格式(输入文件newbarn.in)
第一行一个整数N。
接下来N行,每行两个整数Xi,Yi。
输出格式(输出文件newbarn.out)
两个整数。最小距离和可行位置个数。
样例数据
Input
4
1 -3
0 1
-2 1
1 -1
output
10 4
解释:(0,−1),(0, 0), (1, 0), (1, 1)
数据规模
2<=N<=10000
其他数字绝对值小于等于10000。
题解:
也不能说是题解吧,我自己最后打着打着发现我的方法(可以说成是半个贪心吧)是错误的。留着代码当做纪念,再感受一下吧
代码(PS:还没打完,还有将近一半)
#include<bits/stdc++.h>
using namespace std;
long long n,l,r,ll,rr,num,flag,p=1000003,minl,maxl,minh,maxh,g[2000000],gg[2000000],ggg[2000000],sum,ans,ha[1000000],lie[1000000],a[1000000],b[1000000],aa[1000000],bb[1000000],qh[1000000],ql[1000000];
long long hash(long long t,long long l,long long r){
long long i=t%p;
while(g[i]&&(gg[i]!=l||ggg[i]!=r))i=(i+1)%p;
return i;
}
int main(){
//freopen("newbarn.in","r",stdin);
//freopen("newbarn.out","w",stdout);
long long t,k,i,j;
scanf("%lld",&n);
minh=100000000;minl=100000000;
for(i=1;i<=n;i++){
scanf("%lld%lld",&a[i],&b[i]);
t=a[i]*b[i];
k=hash(t,a[i],b[i]);
g[k]=1;gg[i]=a[i];ggg[i]=b[i];
a[i]+=100000;b[i]+=100000;
ha[a[i]]++;lie[b[i]]++;
minh=min(minh,a[i]);maxh=max(maxh,a[i]);
minl=min(minl,b[i]);maxl=max(maxl,b[i]);
}
for(i=minh+1;i<=maxh;i++)aa[i]=aa[i-1]+ha[i-1];
for(i=minh;i<=maxh;i++)qh[i]=qh[i-1]+n-aa[i]-aa[i];
for(i=minh;i<=maxh;i++)
if(qh[i]>sum){
sum=qh[i];
l=i;
}
for(i=maxh;i>=minh;i--)
if(qh[i]==sum){
r=i;
break;
}
sum=0;
for(i=minl+1;i<=maxl;i++)bb[i]=bb[i-1]+lie[i-1];
for(i=minl;i<=maxl;i++)ql[i]=ql[i-1]+n-bb[i]-bb[i];
for(i=minl;i<=maxl;i++)
if(ql[i]>sum){
sum=ql[i];
ll=i;
}
for(i=maxl;i>=minl;i--)
if(ql[i]==sum){
rr=i;
break;
}
sum=0;
for(i=1;i<=n;i++)sum+=abs(l-a[i])+abs(ll-b[i]);
num=1000000000;
ans=(r-l+1)*(rr-ll+1);
for(i=1;i<=n;i++)
if(a[i]>=l&&a[i]<=r&&b[i]>=ll&&b[i]<=rr){
ans--;
}
if(ans==0){
//左上角
flag=0;
for(ii=1;ii<=200;ii++){
for(i=l-ii;i<l;i++){
j=ll-ii;
t=i*j;
k=hash(t,i,j);
if(!g[k]){
if(sum+qh[l]-qh[i]+ql[ll]-ql[j]<num){
num=sum+qh[l]-qh[i]+ql[ll]-ql[j];
ans=1;
}
else if(sum+qh[l]-qh[i]+ql[ll]-ql[j]==num)ans++;
flag=1;
}
}
for(j=ll-ii;j<ll;j++){
i=l-ii;
t=i*j;
k=hash(t,i,j);
if(!g[k]){
if(sum+qh[l]-qh[i]+ql[ll]-ql[j]<num){
num=sum+qh[l]-qh[i]+ql[ll]-ql[j];
ans=1;
}
else if(sum+qh[l]-qh[i]+ql[ll]-ql[j]==num)ans++;
flag=1;
}
}
}
flag=0;
for(i=l-1;i>=minh-1;i--){
for(j=ll;j<=rr;j++){
t=i*j;
k=hash(t,i,j);
if(!g[k]){
if(sum+qh[l]-qh[i]<num){
num=sum+qh[l]-qh[i];
ans=1;
}
else if(sum+qh[l]-qh[i]==num)ans++;
flag=1;break;
}
}if(flag)break;}
flag=0;
for(i=r+1;i<=maxh+1;i++){
for(j=ll;j<=rr;j++){
t=i*j;
k=hash(t,i,j);
if(!g[k]){
if(sum+qh[i]-qh[r]<num){
num=sum+qh[i]-qh[r];
ans=1;
}
else if(sum+qh[i]-qh[r]==num)ans++;
flag=1;break;
}
}
if(flag)break;
}
flag=0;
for(i=ll-1;i>=minl-1;i--){
for(j=l;j<=r;j++){
t=i*j;
k=hash(t,i,j);
if(!g[k]){
if(sum+ql[ll]-ql[i]<num){
num=sum+ql[ll]-ql[i];
ans=1;
}
else if(sum+ql[ll]-ql[i]==num)ans++;
flag=1;break;
}
}
if(flag)break;
}
flag=0;
for(i=rr+1;i<=maxl+1;i++){
for(j=l;j<=r;j++){
t=i*j;
k=hash(t,i,j);
if(!g[k]){
if(sum+ql[i]-ql[rr]<num){
num=sum+ql[i]-ql[rr];
ans=1;
}
else if(sum+ql[i]-ql[rr]==num)ans++;
flag=1;break;
}
}
if(flag)break;
}
printf("%lld %lld",num,ans);
return 0;
}
printf("%lld %lld",sum,ans);
}