SSL 模拟赛 总结(2017.10.18)

来源:互联网 发布:网络信息检索与利用 编辑:程序博客网 时间:2024/06/08 19:34

这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述

T1:
这题我们可以发现:
长方形的面积就是
a* i + b * j -a*b
现在i,j是未知的
我们进一步思考:
发现我们连接圆心到矩形A的一点,就可以有勾股求出圆心到矩形A的a边的距离
即 (i/2)^2=r^2- (a/2)^2
而后可以求出i
j同理可求
然后我们去枚举a,b即可
时间复杂度:((2r)^2)

var   r,a,b,i,j:longint;   ans,sum:extended;begin     readln(r);     for i:=1 to 2*r do       for j:=1 to 2*r do         begin              sum:=i*sqrt(sqr(r)-sqr(i/2))*2+j*sqrt(sqr(r)-sqr(j/2))*2-i*j;              if sum>ans then                 begin                      ans:=sum;                      a:=i;                      b:=j;                 end;         end;     writeln(a);     writeln(b);end.

T2:
这题其实没什么好讲的,选择排序然后注意判断就可以了。。。。
时间复杂度:O(N^2)
N那么小不用快排那么麻烦啦

var   a:array [0..101,1..2] of string;   b,ans:array [0..101] of longint;   n,i,j:longint;   s:string;begin   readln(n);   for i:=1 to n do     begin          readln(s);          j:=pos('.',s);          if j<>0 then          begin             a[i,2]:=copy(s,j+1,length(s)-j);             delete(s,j,length(s)-j+1);          end;          a[i,1]:=s;          b[i]:=i;     end;   for i:=1 to n-1 do     for j:=i+1 to n do       if ((a[i,2]='') and (a[j,2]<>'')) or          ((a[i,2]=a[j,2]) and (a[i,1]>a[j,1])) or          ((a[i,2]<>'') and (a[j,2]<>'') and (a[i,2]>a[j,2]))          then begin                     a[0]:=a[i];a[i]:=a[j];a[j]:=a[0];                     b[0]:=b[i];b[i]:=b[j];b[j]:=b[0];               end;   for i:=1 to n do     ans[b[i]]:=i;   for i:=1 to n do writeln(ans[i]);end.

T3:
这题其实搜索,然后记忆化:
我们用f[i,j,k]去表示以a[i,j]为起点向4个方向能走的最长等差数列的长度。
然后去搜即可。
你可以在做f[i,j,k]顺便把经过的[ii,jj]的f[ii,jj,kk]做了,然后打个标记,所以跑得特别的快。
时间复杂度:O(4NM)

const    dx:array[1..4] of integer=(0,0,1,-1);    dy:array[1..4] of integer=(-1,1,0,0);var    f:array [0..101,0..101,1..4] of longint;    a:array [0..101,0..101] of longint;    i,j,k,ans,n,m:longint;function check(aa,bb:longint):boolean;begin    if (aa<1) or (aa>n) or (bb<1) or (bb>m) then exit(false);    exit(true);end;function dfs(x,y,z:longint):longint;var    i,p,q:longint;begin    dfs:=1;    for i:=1 to 4 do    begin        p:=x+dx[i];        q:=y+dy[i];        if check(p,q) then         if a[p,q]-a[x,y]=z then         begin            if f[x,y,i]=0 then f[x,y,i]:=dfs(p,q,z)+1;            if f[x,y,i]>dfs then dfs:=f[x,y,i];         end;    end;end;begin    readln(n,m);    for i:=1 to n do      begin          for j:=1 to m do read(a[i,j]);          readln;      end;    for i:=1 to n do      for j:=1 to m do        for k:=1 to 4 do        begin            if check(i+dx[k],j+dy[k]) then              if a[i+dx[k],j+dy[k]]-a[i,j]>0 then                 f[i,j,k]:=dfs(i+dx[k],j+dy[k],a[i+dx[k],j+dy[k]]-a[i,j]);            inc(f[i,j,k]);        end;    for i:=1 to n do      for j:=1 to m do        for k:=1 to 4 do          if f[i,j,k]>ans then ans:=f[i,j,k];    writeln(ans);end.

T4:
这题其实就是取n-1条边,使它变成一棵连通图,然后最大的边最小!如果有克鲁斯卡尔去做,很明显N^3,会炸,所以我们要优化!
我们先将边排序,然后从小到大加边,这样能保证树最大的边最小!
每次加边的时候,要判断2个点并不能互相到达,这点可以用并查集实现!
加到n-1条边的时候,这条边就是答案!
时间复杂度:O(N^2log N)

var    c:array [0..1000001,1..2] of longint;    a:array [0..1001,0..1001] of real;    f,x,y,r:array [0..1001] of longint;    d:array [0..1000001] of real;    i,j,k,l,n,m:longint;    min,ans:real;function find(x:longint):longint;begin    if f[x]=x then exit(x);    f[x]:=find(f[x]);    exit(f[x]);end;procedure qsort(l,r:longint);var    mid,i,j:longint;begin    if l>=r then exit;    i:=l; j:=r;    mid:=(l+r) div 2;    repeat         while d[i]<d[mid] do inc(i);         while d[j]>d[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];                inc(i); dec(j);           end;    until i>j;    qsort(i,r);    qsort(l,j);end;begin    readln(n);    for i:=1 to n do    begin        readln(x[i],y[i],r[i]);        f[i]:=i;    end;    m:=0;    for i:=1 to n-1 do      for j:=i+1 to n do        begin            a[i,j]:=sqrt(sqr(x[i]-x[j])+sqr(y[i]-y[j]))-r[i]-r[j];            if a[i,j]<0 then a[i,j]:=0;            inc(m);            d[m]:=a[i,j];            c[m,1]:=i;            c[m,2]:=j;        end;    qsort(1,m);    k:=1;    ans:=d[1];    f[c[1,2]]:=c[1,1];     for i:=2 to m do          begin               if k=n-1 then break;               if find(c[i,1])<>find(c[i,2])               then begin                      inc(k);                      f[find(c[i,2])]:=find(c[i,1]);                    end;          end;     if d[i-1]>trunc(d[i-1]) then d[i-1]:=d[i-1]+0.5;     writeln(d[i-1]:0:0);end.
原创粉丝点击