jzoj 2017.9.30 模拟赛

来源:互联网 发布:淘宝 运营 系统架构 编辑:程序博客网 时间:2024/06/10 05:16

T1:
水果盛宴:
题目大意:
贝茜的有一个饱腹值上限 T,吃一个橘子会增加她 A 点饱腹值,吃一个柠檬会增加她 B 点饱腹值,橘子跟柠檬吃不完。
如果她愿意,贝茜可以最多喝一次水,这会立即使她的饱腹值变成一半。
帮助贝茜求出她可以获得的最大饱腹值。

1<=T<=5,000,000,1<=A,B<=T
题解:

从0开始去递归它出现的所有情况,在里面找一个最大值,注意越界和重复情况即可。
时间复杂度最大是O(N)

var    cp:array [0..5000001] of boolean;    t,a,b,ans:longint;procedure dg(dep,rp:longint);begin    if (cp[dep]) or (dep>t) then exit;    if dep>ans then ans:=dep;    cp[dep]:=true;    dg(dep+a,rp);    dg(dep+b,rp);    if rp=0 then dg(dep div 2,1);end;begin    readln(t,a,b);    dg(0,0);    writeln(ans);end.

T2:
愤怒的奶牛2:
有N捆干草包位于这一行的不同整数位置x1,x2,…,xN,如果一头奶牛以能量R着陆在了位置x,那么会引起半径为R(R-x..R+x)的爆炸,并摧毁范围内的所有干草包。一共有K头奶牛允许被用来作为炮弹,每头奶牛的能量R都相同。请帮忙决定这个最小的能量,使得用这K头奶牛可以摧毁所有的干草包。

1<=N<=50,000,1<=K<=10
0<=xi<=1,000,000,000
题解:
排序+二分:
将位置排序,然后我们二分它的答案R每次判断取mid时候可以炸掉所有的,可以就向前,不然向后即可

时间复杂度:O(n log2 n+log2(max(xi)/K)*N)

var    a:Array [0..50001] of longint;    l,r,i,j,k,n,m,mid:longint;procedure qsort(l,r:longint);var    i,j,mid:longint;begin    if l>=r then exit;    i:=l; j:=r;    mid:=a[(l+r) div 2];    repeat          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;    until i>j;    qsort(i,r);    qsort(l,j);end;begin     readln(n,m);     for i:=1 to n do       readln(a[i]);     qsort(1,n);     l:=0; r:=(a[n]-a[1]+1) div m+1;     while l+1<r do      begin           j:=1;           mid:=(l+r) div 2;           k:=0;           for i:=1 to n-1 do             begin                  k:=k+(a[i+1]-a[i]);                  if k>2*mid then                     begin                         inc(j);                         k:=0;                     end;             end;           if j<=m then r:=mid                   else l:=mid;      end;     writeln(r);end.

T3:
采访:
题目大意:
你去采访n个国家的领导人。一个领导人要消耗时间t[i],可以收获价值为v[i]的信息。
但有一些国家之间的关系属于敌对关系,因此如果一个国家的领导人知道你采访了他的敌对国家领导人,那么他就会拒绝你的采访。
总之,你采访的国家中,任意选出一对国家都不能构成敌对关系,你才能够完成你的采访,否则某些部分就要落空。
你的Boss他给了你一个时间限制T,求在时间限制T内完成的采访累计起来的价值总和最大。

60%的数据:m=1;
100%的数据:0≤T≤50000,0≤n≤500,1≤m≤10,n=∑m[i]且敌对关系中每个国家编号只会出现一次。

题解:
DP:
设f[i,j]表示前i个关系圈花费时间为j能获得的最大价值总和是多少。
f[i,j]=max{f[i-1,j-t[i,k]]+v[i,k]}
i枚举关系圈 j枚举时间 k枚举I关系圈的某个领导人
时间复杂度:O(MT)

var    f:array [0..11,0..50001] of longint;    num:array [0..11,0..501] of longint;    v,t:array [0..501] of longint;    i,j,k,l,d,n,m,ans:longint;function max(aa,bb:longint):longint;begin    if aa>bb then exit(aa);    exit(bb);end;begin    readln(d,n,m);    for i:=1 to n do      readln(t[i],v[i]);    for i:=1 to m do      begin           read(num[i,0]);           for j:=1 to num[i,0] do read(num[i,j]);           readln;      end;    for i:=1 to m do    begin       for j:=0 to d do f[i,j]:=f[i-1,j];       for j:=1 to num[i,0] do         for k:=d downto t[num[i,j]] do           f[i,k]:=max(f[i,k],f[i-1,k-t[num[i,j]]]+v[num[i,j]]);    end;    writeln(f[m,d]);end.

T4:
房间开灯:
题目大意:
Farmer John正在修建一包含N*N个房间的牲口棚,房间从(1,1)标号到(N,N)。贝茜这头奶牛想要尽可能地开更多房间的灯。她从房间(1,1)出发,一开始只有(1,1)亮着,在一些房间中,她会找到一些电灯开关,这些开关她可以用来切换其他房间的灯的状态。贝茜只能进电灯开着的房间,并且贝茜只能从房间(x,y)走到四个方向的房间(x-1,y),(x+1,y),(x,y-1)和(x,y+1)(如果在边界的话,那可能会更少)
请帮忙统计贝茜最多可以照亮多少房间。

2<=N<=100,1<=M<=20,000

题解:
宽搜:
这题就是广搜:
①枚举肯定不能去M^2的去找,所以我用了二维邻接表
②广搜:
(1)每次加入队列的点要求能从[1,1]到达
(2)每搜完一次就将队列里的坐标拿出来枚举4周看一下有没有可以加入队列的,保证没有缺漏

时间复杂度:O( (NM)^2 +M )

const    dx:array [1..4] of integer=(0,0,1,-1);    dy:array [1..4] of integer=(1,-1,0,0);var    p,cp,map:array [0..101,0..101] of boolean;    list:array [0..101,0..101] of longint;    next,px,py,qx,qy:array [0..20001] of longint;    q:array [0..200001,1..2] of longint;    i,j,n,m,ans:longint;procedure find;var    head,tail,i,j,k:longint;begin    head:=0;    tail:=1;    map[1,1]:=true;    cp[1,1]:=true;    p[1,1]:=true;    q[1,1]:=1;    q[1,2]:=1;    while head<tail do    begin          inc(head);          i:=list[q[head,1],q[head,2]];          while i>0 do          begin               map[qx[i],qy[i]]:=true;               i:=next[i];          end;          for k:=1 to head do            for j:=1 to 4 do             if map[q[k,1]+dx[j],q[k,2]+dy[j]] then                if not(p[q[k,1]+dx[j],q[k,2]+dy[j]]) then                   begin                         inc(tail);                         q[tail,1]:=q[k,1]+dx[j];                         q[tail,2]:=q[k,2]+dy[j];                         p[q[k,1]+dx[j],q[k,2]+dy[j]]:=true;                   end;    end;end;begin    readln(n,m);    for i:=1 to m do      begin            readln(px[i],py[i],qx[i],qy[i]);            next[i]:=list[px[i],py[i]];            list[px[i],py[i]]:=i;      end;    find;    for i:=1 to n do      for j:=1 to n do        if map[i,j] then inc(ans);    writeln(ans);end.
原创粉丝点击