2016普级组模拟试题(20161114) Vojnici
Time Limit:10000MS Memory Limit:256000K
Total Submit:4 Accepted:0
Case Time Limit:1000MS
Description
Perica在电脑上玩一种游戏。他有n个士兵,每个士兵有一定的强壮程度。电脑也有n个士兵,每个士兵也有自己的强壮程度。这2n个士兵的强壮程度互不相同。Perica要指挥他的士兵攻击电脑的士兵使得每个士兵恰好和一个敌人战斗。
每个电脑的士兵有两个值,第一个值表示如果Perica赢了这个士兵,赢得的分数,第二个值表示如果电脑的士兵获胜了,Perica丢失的分数。
假设强壮的士兵总能获胜,问Perica能取得的最高分数。
Input
输入文件vojnici.in第一行一个整数n。
第二行n个整数表示Perica的n个士兵的强壮程度,
第三行n个整数表示电脑的n个士兵的强壮程度,
第四行n个整数表示电脑的n个士兵的第一个值,
第五行n个整数表示电脑的n个士兵的第二个值。
Output
输出文件vojnici.out Perica能赢得的最多的分数。
Sample Input
3
9 12 3
4 5 6
10 2 7
5 3 1
Sample Output
14
Hint
数据范围
20%的数据,n<=10。
50%的数据,n<=2000。
100%的数据,1<=n<=100000,强壮程度取值范围[0, 2000000000],电脑士兵的两个值取值范围[0,1000]。
本题对于现在的我还是偏难的,方法还是很容易,就是赢得分加上输的分排序后,每一个有序分数找出他的最近比他大的己方士兵的选出来打一架就好了。最后留下来的就减去他们会输的分数就好了。主要是如何查抄一个比他大的最小数。就可以用到平衡树来维护他的性质。(我没有用,卡过去的)。
const
maxn=500000;
var
a,b,c,d,s:array [0..maxn] of int64;
f,o:array [0..maxn] of boolean;
n,m,p,ans:int64;
flag:boolean;
i,j:longint;
procedure init;
var
i,j:longint;
begin
readln(n);
for i:=1 to n do
read(a[i]);
readln;
for i:=1 to n do
read(b[i]);
readln;
for i:=1 to n do
read(c[i]);
readln;
for i:=1 to n do
read(d[i]);
for i:=1 to n do
c[i]:=c[i]+d[i];
end;
procedure qsort1(l,r:longint);
var
i,j:longint;
mid:int64;
begin
i:=l; j:=r;
mid:=a[(l+r) div 2];
while i<j do
begin
while a[i]>mid do inc(i);
while a[j]<mid do dec(j);
if i<=j then
begin
a[0]:=a[i];
a[i]:=a[j];
a[j]:=a[0];
inc(i); dec(j);
end;
end;
if l<j then qsort1(l,j);
if r>i then qsort1(i,r);
end;
procedure qsort(l,r:longint);
var
i,j:longint;
mid:int64;
begin
i:=l; j:=r;
mid:=c[(l+r) div 2];
while i<j do
begin
while c[i]>mid do inc(i);
while c[j]<mid do dec(j);
if i<=j then
begin
d[0]:=d[i];
d[i]:=d[j];
d[j]:=d[0];
c[0]:=c[i];
c[i]:=c[j];
c[j]:=c[0];
b[0]:=b[i];
b[i]:=b[j];
b[j]:=b[0];
inc(i); dec(j);
end;
end;
if l<j then qsort(l,j);
if r>i then qsort(i,r);
end;
procedure sort(l,r:longint;x:int64);
var
mid,i,j:longint;
begin
mid:=(l+r) div 2;
if l>r then exit;
if (a[mid]>x) and (a[mid+1]>x) then sort(mid+1,r,x)
else if (a[mid]<x) then sort(l,mid-1,x)
else if (a[mid]>x) then
begin
while o[mid]=true do dec(mid);
if mid=0 then exit;
p:=mid;
o[mid]:=true;
flag:=true;
exit;
end;
end;
begin
assign(input,'vojnici.in'); reset(input);
assign(output,'vojnici.out'); rewrite(output);
init;
qsort(1,n);
qsort1(1,n);
a[0]:=0;
c[0]:=0;
d[0]:=0;
for i:=1 to n do
s[i]:=i;
for i:=1 to n do
begin
flag:=false;
sort(1,n,b[i]);
if flag=true then
begin
f[i]:=true;
ans:=ans+c[i]-d[i];
end;
end;
for i:=1 to n do
if f[i]=false then ans:=ans-d[i];
writeln(ans);
close(input); close(output);
end.
优化:这个是某个大神给的博客,大家可以去看看
http://blog.csdn.net/niteip/article/details/11840691/