SSL 模拟赛 总结(2017.10.18)

SSL 模拟赛 总结(2017.10.18)_第1张图片

SSL 模拟赛 总结(2017.10.18)_第2张图片

SSL 模拟赛 总结(2017.10.18)_第3张图片

SSL 模拟赛 总结(2017.10.18)_第4张图片

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]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.


你可能感兴趣的:(规律与思维,排序&拓扑,并查集,深搜dfs,暴力/枚举/模拟)