jzoj 2017.10.08 模拟赛

T1:
桐桐的雷达:
测试雷达都有一个最高限速和一个最低限速。行驶速度超过最高限速B或低于最低限速A,都认为是违规的。
为了检测探测器是否正常工作,假设多数驾驶员是遵守交通规则的,因此如果有超过10%的数据是违规的,则认为探测器可能出了问题。共有C个人,计算合法速度的平均速度。如果你判断出是探测器坏了,则输出0.0。

1≤A≤200, A≤B≤200, 1≤C≤50

题解:
没什么好说的, < min 亦或者 > max 都sum+=1
然后10sum>c就输出0.0
可以就输出平均速度,不过是合法速度的平均而不是全部的平均

时间复杂度:O(C)

var
   ans,a,b,c,i,j,x:longint;
begin
    assign(input,'radar.in'); reset(input);
    assign(output,'radar.out');rewrite(output);
     readln(a,b,c);
     ans:=0; j:=0;
     for i:=1 to c do
      begin
           read(x);
           if (x<a) or (x>b)
              then inc(j)
              else ans:=ans+x;
      end;
     if j*10>c
        then writeln('0.0')
        else writeln(ans/(c-j):0:4);
     close(input); close(output);
end.

T2:
桐桐的游戏:
桐桐最近在玩一个跳棋游戏,规则是:有个圆圈,分成N等分,顺时针标号为1到N。假设其中有些段是障碍。桐桐从1号段出发,每次顺时针跳K段,目标是跳到第Z号段,但过程中不能跳到障碍段上去。桐桐想请你帮忙,给出N,Z,以及M个障碍的位置,求出最小的K。

2≤N≤1000, 2≤Z, 0 ≤M≤N-2

题解:
模拟即可
因为答案K 的范围 1≤K≤N,所以可以枚举
对于一个枚举到的i,
从1开始每次跳i步
不过注意,
①跳到障碍物,退出
②跳出死循环,退出
③跳到点Z,退出直接输出

这样时间复杂度是O(N^2)

var
   a,b:array [0..1001] of boolean;
   i,j,n,m,z,x:longint;

begin
    assign(input,'comfort.in'); reset(input);
    assign(output,'comfort.out');rewrite(output);
     readln(n,z,m);
     for i:=1 to m do
      begin
            read(x);
            b[x]:=true;
      end;
     for i:=1 to n do
       begin
            for j:=1 to n do a[j]:=false;
            j:=1; a[1]:=true;
            while not(a[z]) do
            begin
                  j:=j+i;
                  if j>n then j:=j mod n;
                  if (b[j]) or (a[j]) then break;
                  a[j]:=true;
            end;
            if a[z] then
               begin
                     writeln(i);
                     close(input); close(output);
                     halt;
               end;
       end;
end.

T3;
桐桐偶然发现一个递归函数w(a,b,c)有以下性质:
如果a<=0 or b<=0 or c<=0就返回值1;
如果a>20 or b>20 or c>20就返回w(20,20,20);
如果a < b并且b < c就返回w(a,b,c-1)+w(a,b-1,c-1)-w(a,b-1,c);
其它别的情况就返回w(a-1,b,c)+w(a-1,b-1,c)+w(a-1,b,c-1)-w(a-1,b-1,c-1)。
给出a,b,c,求出这个简单的递归函数的值。

-50≤a,b,c≤50

题解:
这题其实很简单,就是一个递归
注意一下

a<=0 or b<=0 or c<=0就返回值1
这里照做即可

如果a >20 or b>20 or c >20就返回w(20,20,20);
这里可以在递归过程中求出w(20,20,20)然后直接去用这个w(20,20,20)的值,当作一个已知值去做,因为这是可求的,为1048576,就可以省很多这种情况的时间


如果a < b并且b < c
返回w(a,b,c-1)+w(a,b-1,c-1)-w(a,b-1,c);
其它别的情况
返回w(a-1,b,c)+w(a-1,b-1,c)+w(a-1,b,c-1)-w(a-1,b-1,c-1)
照做

这种分治题其实就特别容易了,注意一下对其能做的小优化,以及细节即可得分=- =

var
    w:array [-51..51,-51..51,-51..51] of longint;
    a,b,c,i,j,k:longint;

procedure dfs(x,y,s:longint);
begin
     if w[x,y,s]>0 then exit;
     if (x<=0) or (y<=0) or (s<=0) then begin w[x,y,s]:=1; exit; end;
     if (x>20) or (y>20) or (s>20) then begin w[x,y,s]:=1048576; exit end;

     if (x<y) and (y<s) then
     begin
         dfs(x,y,s-1); dfs(x,y-1,s-1); dfs(x,y-1,s);
         w[x,y,s]:=w[x,y,s-1]+w[x,y-1,s-1]-w[x,y-1,s];
     end else
     begin
         dfs(x-1,y,s); dfs(x-1,y-1,s); dfs(x-1,y,s-1); dfs(x-1,y-1,s-1);
         w[x,y,s]:=w[x-1,y,s]+w[x-1,y-1,s]+w[x-1,y,s-1]-w[x-1,y-1,s-1];
     end;
end;
begin
     assign(input,'function.in'); reset(input);
     assign(output,'function.out');rewrite(output);
     readln(a,b,c);
     write('w(',a,', ',b,', ',c,') = ');
     dfs(a,b,c);
     write(w[a,b,c]);
     writeln;
     close(input); close(output);
 end.

T4;
桐桐的新闻系统:
桐桐设计了一套新闻系统——Argus。
向Argus注册的指令具有以下格式:
Register Q_num Period
Q_num 是用户的ID, Period是间隔。注册后Period 秒,结果会第一次到达。
所有的用户都有不同的 Q_num。桐桐测试了一段时间后,想知道系统前K次发送给谁新闻了。如果同一时间发送多个新闻,以 Q_num 的升序排列。

指令数不超过1000,K<= 10000
0 < Q_num <= 3000
0 < Period <= 3000

题解:
这题一开始我用堆做,结果弄得很长,后来发现数据特别小,所以排序以后暴力枚举一下也可以。
我们先对Q_num进行排序,~~快排这时比不过插排!~
~
然后我们每次在里面找一个最小的时间t[i]输出,
然后将这个ID下一次发送的时间tt[i]求出来,即加上
Qi_Period。
下一次也是这样找最小值
因为Q_num排序了的原因我们可以忽略它的t[]相等的情况,所以程序就特别好写了

时间复杂度:O(n log n+K*指令数)

var
    rp:array [0..1001,1..3] of longint;
    x,y,i,j,k,l,n:longint;
    s,p:ansistring;

procedure qsort(l,r:longint);
var
    i,j,mid:longint;
begin
    if l>=r then exit;
    i:=l; j:=r;
    mid:=rp[(l+r) div 2,3];
    repeat
         while (rp[i,3]<mid) do inc(i);
         while (rp[j,3]>mid) do dec(j);
         if i<=j then
          begin
               rp[0]:=rp[i];
               rp[i]:=rp[j];
               rp[j]:=rp[0];
               inc(i); dec(j);
          end;
    until i>j;
    qsort(i,r);
    qsort(l,j);
end;

begin
    assign(input,'argus.in'); reset(input);
    assign(output,'argus.out'); rewrite(output);
    readln(s);
    n:=0;
    while s<>'#' do
    begin
        j:=pos(' ',s); delete(s,1,j); j:=pos(' ',s);
        p:=copy(s,1,j-1); val(p,x);
        delete(s,1,j); val(s,y);

        inc(n);
        rp[n,1]:=y;
        rp[n,2]:=y;
        rp[n,3]:=x;

        readln(s);
    end;
    qsort(1,n);
    readln(k);
    for i:=1 to k do
      begin
            l:=1;
            for j:=2 to n do
              if (rp[j,1]<rp[l,1]) then l:=j;
            writeln(rp[l,3]);
            rp[l,1]:=rp[l,1]+rp[l,2];
      end;
    close(input); close(output);
end.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值