1.中位数
思路:我们可以很简单的想到两层循环递推的做法,可是数据较大,无法循环。我们只能另找通路。
10^6可以被一层循环完美的解决,所以我们从这方面入手。
我们可以预处理!
(1)找到中位数的位置
(2)从中位数向两边扩展
(3)统计大于其的个数,计入桶中
(4)搜桶,据乘法原理可知,所有互为相反数的桶中数的乘积之和即为答案。
参考程序:
var
n,ans,b,i,p,k:longint;
a,x,y:array[-100001..100001]of longint;
begin
assign(input,'median.in');reset(input);
assign(output,'median.out');rewrite(output);
readln(n,b);
for i:=1 to n do
begin
read(a[i]);
if a[i]=b then p:=i;
end;
x[0]:=1;y[0]:=1;
for i:=p-1 downto 1 do
begin
if a[i]>b then k:=k+1 else k:=k-1;
x[k]:=x[k]+1;
end;
k:=0;
for i:=p+1 to n do
begin
if a[i]>b then k:=k+1 else k:=k-1;
y[k]:=y[k]+1;
end;
for i:=-n to n do
ans:=ans+x[i]*y[-i];
write(ans);
close(input);close(output);
end.
2.敲砖
思路:动态规划。很明显以行来动归是行不通了,我们从列入手。
参考程序:
var
n,m,i,j,k,l,max:longint;
f:array[0..60,0..510,0..60]of longint;
a,s:array[0..60,0..60]of longint;
x:array[0..60]of longint;
begin
assign(input,'brike.in');reset(input);
assign(output,'brike.out');rewrite(output);
readln(n,m);
for i:=1 to n do
for j:=1 to n-i+1 do
begin
read(a[i,j]);
s[j,i]:=s[j,i-1]+a[i,j];
end;
for i:=1 to n do x[i]:=x[i-1]+i;
f[n+1,0,0]:=0;
for i:=n downto 1 do
for j:=0 to n-i+1 do
for k:=j-1 to n-i do
for l:=j+x[k] to m do
if f[i,l,j]<f[i+1,l-j,k]+s[i,j] then
f[i,l,j]:=f[i+1,l-j,k]+s[i,j];
for i:=1 to n do
for j:=0 to n-i+1 do
if f[i,m,j]>max then max:=f[i,m,j];
write(max);
close(input);close(output);
end.
4.单词
思路:有陷阱,太简单,直接见程序。
参考程序:
var
x:array[0..110000]of string;
m,i,n:longint;
t:string;
procedure kp(l,r:longint);
var
i,j:longint;
t,a:string;
begin
i:=l;j:=r;a:=x[random(r-l+1)+l];
repeat
while x[i]<a do i:=i+1;
while x[j]>a do j:=j-1;
if i<=j then
begin
t:=x[i];x[i]:=x[j];x[j]:=t;
i:=i+1;j:=j-1;
end;
until i>j;
if i<r then kp(i,r);
if j>l then kp(l,j);
end;
begin
assign(input,'words.in');reset(input);
assign(output,'words.out');rewrite(output);
randomize;
readln(n);
for i:=1 to n do
readln(x[i]);
readln(t);
for i:=1 to n do
if pos(t,x[i])=1 then
begin m:=m+1;x[m]:=x[i];end;
kp(1,m);
for i:=1 to m do
writeln(x[i]);
close(input);close(output);
end.
4.邮递员
思路:正反向两次spfa
参考程序:
var
n,m,i,oo,x,y,z,head,ans,t,tail,j:longint;
dis,q:array[0..1100]of longint;
map,tt:array[0..1100,0..1100]of longint;
inq:array[0..1100]of boolean;
procedure spfa;
var
head,tail:longint;
begin
fillchar(inq,sizeof(inq),0);
fillchar(dis,sizeof(dis),$7f shr 2);
head:=0;tail:=1;
dis[1]:=0;inq[1]:=true;q[1]:=1;
while head<>tail do
begin
head:=head mod n+1;
i:=q[head];
inq[i]:=false;
for j:=1 to n do
if dis[i]+map[i,j]<dis[j] then
begin
dis[j]:=dis[i]+map[i,j];
if not inq[j] then
begin
tail:=tail mod n+1;
inq[j]:=true;
q[tail]:=j;
end;
end;
end;
for i:=1 to n do ans:=ans+dis[i];
end;
begin
assign(input,'post.in');reset(input);
assign(output,'post.out');rewrite(output);
readln(n,m);
fillchar(map,sizeof(map),$7f shr 2);tt:=map;
oo:=map[0,0];
for i:=1 to m do
begin
readln(x,y,z);
if z<map[x,y] then map[x,y]:=z;
if z<tt[y,x] then tt[y,x]:=z;
end;
spfa;map:=tt;spfa;
write(ans);
close(input);close(output);
end.