31 条题解
-
1他的亲野爹 LV 8 @ 2019-04-05 10:11:44
#include <stdio.h> #include <string.h> #include <math.h> //int tmp[10005]; int swap(int *a, int *b) { int tmp=*a; *a=*b; *b=tmp; return 0; } int * sort (int * data,int a,int b) { int n=b-a+1,m=a+(b-a)/2,i,j,k;// printf("enter sort %d %d \n",a,b); if(n<=2) { if(data[a]>data[b]) swap(&data[a],&data[b]); } else { sort(data, a, m); sort(data,m+1,b); j=a; k=m+1; int tmp[b+10]; /* for(i=a;i<=b;i++) { if((data[j]<data[k]||k>b)&&j<=m) { tmp[i]=data[j]; j++; } if((data[j]>=data[k]||j>m)&&k<=b) { tmp[i]=data[k]; k++; } }*/ i=a; while(j<=m&&k<=b) { if(data[j]<=data[k]) { tmp[i]=data[j]; j++; } else { tmp[i]=data[k]; k++; } i++; } if(j>m) { while(k<=b) { tmp[i]=data[k]; k++; i++; } } else if(k>b) { while(j<=m) { tmp[i]=data[j]; j++; i++; } } for(i=a;i<=b;i++) data[i]=tmp[i]; // for(i=a;i<=b;i++)printf("%d\t",tmp[i]);printf("\n"); } //for(i=a;i<=b;i++) printf("%d\t",data[i]);printf("\n"); return data; } int main() { int N,i; scanf("%d",&N); int x[N],y[N]; memset(x,0,sizeof(x)); memset(y,0,sizeof(y)); for(i=0;i<N;i++) scanf("%d %d",&x[i],&y[i]); sort(y,0,N-1); int ans=0; for(i=0;i<N;i++) ans+=abs(y[i]-y[N/2]); //for(i=0;i<N;i++) printf("%d\n",y[i]); sort(x,0,N-1); for(i=0;i<N;i++) x[i]=x[i]-i; sort(x,0,N-1); for(i=0;i<N;i++) ans+=abs(x[i]-x[N/2]); printf("%d",ans); return 0; }
-
12008-11-06 18:31:08@
由于是求曼哈顿距离,所以可以将x, y分量分开考虑。
y: 要将所有的yi集中到某个y0上。可以通过微量法证明y0一定在某个已知yi上。再通过微量法证明y0一定是yi的中位数。
x: 要将所有的x1集中到某个x0。其他xi依次相间1排下去。
先将x排序,可以证明x的顺序一定就是最终的序列的顺序(因为交叉位置的话解更差)。由于定了序,所以有xi = x0 + i - 1,则可以将问题转化为x'i = xi - (i - 1) = x0。x'就是与y同样的问题了,求xi - (i - 1)的中位数x0就可以了。 -
02016-11-30 12:02:46@
评测结果 编译成功 foo.cpp: In function 'int main()': foo.cpp:13:19: warning: suggest parentheses around '+' inside '>>' [-Wparentheses] ans += abs(x[n+1>>1]-x[i])+abs(y[n+1>>1]-y[i]); ^ foo.cpp:13:39: warning: suggest parentheses around '+' inside '>>' [-Wparentheses] ans += abs(x[n+1>>1]-x[i])+abs(y[n+1>>1]-y[i]); ^ 测试数据 #0: Accepted, time = 0 ms, mem = 588 KiB, score = 10 测试数据 #1: Accepted, time = 0 ms, mem = 588 KiB, score = 10 测试数据 #2: Accepted, time = 15 ms, mem = 584 KiB, score = 10 测试数据 #3: Accepted, time = 0 ms, mem = 584 KiB, score = 10 测试数据 #4: Accepted, time = 0 ms, mem = 588 KiB, score = 10 测试数据 #5: Accepted, time = 0 ms, mem = 588 KiB, score = 10 测试数据 #6: Accepted, time = 0 ms, mem = 588 KiB, score = 10 测试数据 #7: Accepted, time = 15 ms, mem = 588 KiB, score = 10 测试数据 #8: Accepted, time = 0 ms, mem = 588 KiB, score = 10 测试数据 #9: Accepted, time = 15 ms, mem = 588 KiB, score = 10 Accepted, time = 45 ms, mem = 588 KiB, score = 100 代码 #include <algorithm> #include <cstdio> using namespace std; int n,ans = 0,x[10001],y[10001]; int main() { scanf("%d",&n); for (int i = 1;i <= n;i++) scanf("%d%d",&x[i],&y[i]); sort(x+1,x+n+1); for (int i = 1;i <= n;i++) x[i] -= i-1; sort(x+1,x+n+1); sort(y+1,y+n+1); for (int i = 1;i <= n;i++) ans += abs(x[n+1>>1]-x[i])+abs(y[n+1>>1]-y[i]); printf("%d",ans); return 0; }
-
02015-08-04 14:32:31@
排序或O(N)找中位数都可以,找两遍,(不在同一列是前提,可证第二遍中位数不变数据依然原序递增)
-
02014-08-07 11:20:23@
#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std;
main()
{
int n,i,x[10001],y[10001],s1=0,s2=0;
cin>>n;
for(i=0;i<n;i++)
cin>>x[i]>>y[i];
sort(x,x+n);
sort(y,y+n);
for(i=0;i<n;i++)
x[i]-=i;
sort(x,x+n);
for(i=0;i<n;i++)
{
s1+=abs(x[i]-x[n/2]);
s2+=abs(y[i]-y[n/2]);
}
cout<<s1+s2;
} -
02014-03-07 18:58:18@
一次秒杀!
program p1440;
var a:array[1..10000] of longint;
b,c:array[-10000..10000] of longint;
x,y,x1,y1:array[1..10000] of longint;
sum,n,h:longint;
//
procedure init;
var i:longint;
begin
readln(n);
for i:=1 to n do readln(x[i],y[i]);
if odd(n) then h:=(n+1) shr 1
else h:=n shr 1;
end;
//
procedure main1;
var i:longint;
begin
for i:=1 to n do inc(b[y[i]]);
for i:=-9999 to 10000 do c[i]:=c[i-1]+b[i-1];
for i:=1 to n do
begin
inc(c[y[i]]);
y1[c[y[i]]]:=y[i];
end;
y:=y1;
for i:=1 to n do sum:=sum+abs(y[i]-y[h]);
end;
//
procedure main2;
var i:longint;
begin
fillchar(b,sizeof(b),0);fillchar(c,sizeof(c),0);
for i:=1 to n do inc(b[x[i]]);
for i:=-9999 to 10000 do c[i]:=c[i-1]+b[i-1];
for i:=1 to n do
begin
inc(c[x[i]]);
x1[c[x[i]]]:=x[i];
end;
x:=x1;
for i:=1 to n do x[i]:=x[i]-i+1;
fillchar(b,sizeof(b),0);fillchar(c,sizeof(c),0);
for i:=1 to n do inc(b[x[i]]);
for i:=-9999 to 10000 do c[i]:=c[i-1]+b[i-1];
for i:=1 to n do
begin
inc(c[x[i]]);
x1[c[x[i]]]:=x[i];
end;
x:=x1;
for i:=1 to n do sum:=sum+abs(x[i]-x[h]);
end;
//
procedure print;
begin
write(sum);
end;//
begin
init;
main1;
main2;
print;
end. -
02013-09-08 15:55:24@
编译成功
foo.pas(71,23) Warning: Comment level 2 found
foo.pas(72,23) Warning: Comment level 2 found
测试数据 #0: Accepted, time = 0 ms, mem = 848 KiB, score = 10
测试数据 #1: Accepted, time = 0 ms, mem = 852 KiB, score = 10
测试数据 #2: Accepted, time = 0 ms, mem = 852 KiB, score = 10
测试数据 #3: WrongAnswer, time = 0 ms, mem = 848 KiB, score = 0
测试数据 #4: WrongAnswer, time = 0 ms, mem = 852 KiB, score = 0
测试数据 #5: Accepted, time = 0 ms, mem = 848 KiB, score = 10
测试数据 #6: Accepted, time = 0 ms, mem = 852 KiB, score = 10
测试数据 #7: Accepted, time = 0 ms, mem = 848 KiB, score = 10
测试数据 #8: Accepted, time = 0 ms, mem = 852 KiB, score = 10
测试数据 #9: Accepted, time = 15 ms, mem = 852 KiB, score = 10
WrongAnswer, time = 15 ms, mem = 852 KiB, score = 80
三快排整么用啊?? -
02012-08-02 20:33:56@
VijosNT Mini 2.0.5.6
MyProg Suite Not Found / 0 / 0ms / 0KB
这是什么情况??? -
02009-09-19 21:22:51@
囧囧囧囧囧.......交了3次
第一次快排写反了 0
第二次x y读倒了 20
第三次AC
大体思想同brace_123
对所有的y排序 然后求中位数 然后统计上
对所有的x排序 然后每个x[i]减去(i-1)
然后的处理同y -
02009-08-15 15:07:58@
Accepted 有效得分:100 有效耗时:0ms
三个快排......还是var好用啊 -
02009-08-12 12:33:15@
xi'=x+i-1
k=|x1-x1'|+|x2-x2'|+...+|xn-xn'|
=|x1-(x+i-1)|+|x2-(x+2-1)|+...+|xn-(x+n-1)|
=|(x1-(1-1))-x|+|(x2-(2-1))-x|+...+|(xn-(n-1)-x| -
02009-07-16 15:37:52@
注意:y0不一定要在yi上,如果not odd(n),而且y[n div 2]+y[n div 2+1] mod 2=0就直接用y[n div 2]+y[n div 2+1] div 2的值当中位数.
-
02009-06-05 15:37:09@
编译通过...
├ 测试数据 01:答案正确... 0ms
├ 测试数据 02:答案正确... 0ms
├ 测试数据 03:答案正确... 0ms
├ 测试数据 04:答案正确... 0ms
├ 测试数据 05:答案正确... 0ms
├ 测试数据 06:答案正确... 0ms
├ 测试数据 07:答案正确... 0ms
├ 测试数据 08:答案正确... 0ms
├ 测试数据 09:答案正确... 0ms
├ 测试数据 10:答案正确... 0ms
---|---|---|---|---|---|---|---|-
Accepted 有效得分:100 有效耗时:0ms思路很绕,而且我用的是计数排序,毕竟x,y范围很小。
-
02009-02-18 20:35:37@
一个qsort出现了问题
-
02008-11-07 08:45:19@
编译通过...
├ 测试数据 01:答案正确... 0ms
├ 测试数据 02:答案正确... 0ms
├ 测试数据 03:答案正确... 0ms
├ 测试数据 04:答案正确... 0ms
├ 测试数据 05:答案正确... 0ms
├ 测试数据 06:答案正确... 0ms
├ 测试数据 07:答案正确... 0ms
├ 测试数据 08:答案正确... 0ms
├ 测试数据 09:答案正确... 0ms
├ 测试数据 10:答案正确... 0ms
---|---|---|---|---|---|---|---|-
Accepted 有效得分:100 有效耗时:0ms
三次快排! -
02008-10-27 08:57:19@
我的那个汗..- -
3次Qsort..- -
给我练基础算法么.. -
02008-10-08 21:56:02@
这个程序80分
两个小点挂了
var
x,y,xx:array[1..10000]of longint;
i,j,k,p,n:longint;
s:int64;
procedure sorty(l,r: longint);
var
i,j,mid,t: longint;
begin
i:=l; j:=r; mid:=y[(l+r) shr 1];
repeat
while y[i]j;
if l -
02008-10-04 15:21:44@
简单
-
02008-09-12 22:15:54@
to lemon_cn
中位数的定义就是中间的数...... -
02009-11-06 17:18:48@
y: 要将所有的yi集中到某个y0上。可以通过微量法证明y0一定在某个已知yi上。再通过微量法证明y0一定是yi的中位数。
x: 要将所有的x1集中到某个x0。其他xi依次相间1排下去。
先将x排序,可以证明x的顺序一定就是最终的序列的顺序(因为交叉位置的话解更差)。由于定了序,所以有xi = x0 + i - 1,则可以将问题转化为x'i = xi - (i - 1) = x0。x'就是与y同样的问题了,求xi - (i - 1)的中位数x0就可以了。这个证明非常妙