zoukankan      html  css  js  c++  java
  • 「Nescafé 29」杯HE两校联赛(第二轮Day2)

          这次比赛没有AK的,120分的有57人,我110分,zzm神犇第一题比我多被坑一个点,但是人家第二题想到正解。

    A 穿越七色虹

          二分以后判定是个线段覆盖。忘记去掉在x0右边的区间WA第一个和第三个点,改了以后WA5个点,不想调了。

    program rainbow;
    
    uses math;
    
    const FileName='rainbow';
    
    var x,r,a,b:array[0..10] of extended;
    
        temp,ra,rb,la,lb,left,right,mid,x0,h:extended;
    
        i,time:longint;
    
    procedure swap(var x,y:extended);
    
              var t:extended;
    
              begin t:=x;x:=y;y:=t;end;
    
    function  cmp(i,j:longint):boolean;
    
              begin
    
              if a[i]<a[j] then exit(true);
    
              if a[i]>a[j] then exit(false);
    
              if b[i]<b[j] then exit(true);
    
              if b[i]>b[j] then exit(false);
    
              exit(true);
    
              end;
    
    function  check(n:extended):boolean;
    
              var tot,i,j:longint;
    
                  range,nr,delta:extended;
    
              begin tot:=0;
    
              for i:=1 to 7 do
    
                if r[i]+n>h then
    
                  begin
    
                  nr:=r[i]+n;
    
                  delta:=sqrt(nr*nr-h*h);
    
                  inc(tot);
    
                  a[tot]:=x[i]-delta;
    
                  b[tot]:=x[i]+delta;
    
                  if a[tot]>x0 then dec(tot);
    
                  end;
    
              if tot=0 then exit(false);
    
              //sort
    
              for i:=1 to 6 do
    
                for j:=i to 7 do
    
                  if not cmp(i,j)
    
                    then begin
    
                    swap(a[i],a[j]);
    
                    swap(b[i],b[j]);
    
                    end;
    
              //work
    
              if a[1]>0 then exit(false);
    
              range:=b[1];
    
              for i:=2 to tot do
    
                if a[i]<range
    
                  then range:=max(b[i],range)
    
                  else exit(false);
    
              if range>x0 then exit(true)
    
                          else exit(false);
    
              end;
    
    begin
    
    readln(h,x0);right:=31623;left:=0;time:=0;
    
    for i:=1 to 7 do begin
    
      readln(x[i],r[i]);
    
      la:=x[i];lb:=x0-x[i];
    
      ra:=sqrt(la*la+h*h+10);rb:=sqrt(lb*lb+h*h+10);
    
      if(ra>r[i])or(rb>r[i])
    
        then begin
    
             temp:=-1E6;
    
             if ra*ra-la*la>=h*h then temp:=max(temp,ra-r[i]);
    
             if rb*rb-lb*lb>=h*h then temp:=max(temp,rb-r[i]);
    
             if temp>0 then right:=min(right,temp);
    
             end;
    
      end;
    
    right:=right+h;
    
    if check(0)
    
      then writeln('0.00')
    
      else begin
    
           while(abs(right-left)>1E-6)and
    
                (time<=10000)do
    
             begin
    
             inc(time);
    
             mid:=(left+right)/2;
    
             if check(mid)
    
               then right:=mid
    
               else left:=mid;
    
             end;
    
           writeln(right:2:2);
    
           end;
    
    end.

    B 四叶草魔杖

          看数据范围蒙了个状压DP求最优哈密顿路,骗到30分。据说直接MST能80?

    program clover;
    
    uses math;
    
    const FileName='clover';
    
          inf=maxlongint div 2;
    
    var   u,v,bitset,ans,n,m,fall,i,p,q,t,tot:longint;
    
          f:array[0..16,0..$FFFF] of longint;
    
          w:array[0..16,0..16] of longint;
    
          a:array[0..16] of longint;
    
    begin
    
    readln(n,m);fall:=1<<n-1;ans:=inf;
    
    filldword(w,sizeof(w) shr 2, -1);
    
    filldword(f,sizeof(f) shr 2,inf);
    
    for i:=1 to n do read(A[i]);
    
    for i:=1 to m do
    
       begin
    
       readln(p,q,t);
    
       w[p][q]:=t;
    
       w[q][p]:=t;
    
       end;
    
    for i:=0 to n-1 do f[i][1<<i]:=0;
    
    for bitset:=0 to fall do
    
       for u:=0 to n-1 do if((bitset shr u)and 1)=1 then
    
         for v:=0 to n-1 do if(((bitset shr v)and 1)=1)and(w[v][u]<>-1)
    
           then f[u][bitset]:=min(f[v][bitset xor 1<<u]+w[v][u],f[u][bitset]);
    
    for i:=0 to n-1 do
    
       ans:=min(f[i][fall],ans);
    
    if ans<>inf
    
      then writeln(ans)
    
      else writeln('Impossible');
    
    end.

          等会学一下正解。orz zzm神犇。由于MST搞完cnt不会比N大,所以秒过。应该意识到这是一个MST删边的问题。首先一个MST是可以满足能量的要求的。然后答案应该是几个子图的MST,每个子图sigma(a[i])=0,然后枚举边的所有组合,BFS验证即可。

    #01: Accepted (0ms, 700KB)
    #02: Accepted (0ms, 700KB)
    #03: Accepted (0ms, 700KB)
    #04: Accepted (0ms, 700KB)
    #05: Accepted (0ms, 700KB)
    #06: Accepted (0ms, 700KB)
    #07: Accepted (0ms, 700KB)
    #08: Accepted (0ms, 700KB)
    #09: Accepted (0ms, 700KB)
    #10: Accepted (0ms, 700KB)
    Accepted / 100 / 0ms / 700KB

    program clover;
    
    uses math;
    
    const FileName='clover';
    
          inf=maxlongint div 2;
    
    var   temp,cnt,bitset,ans,n,m,fall,i,j,vi,ui,t,tot:longint;
    
          Q,father:array[0..16] of longint;
    
          map:array[0..16,0..16] of longint;
    
          a:array[0..16] of longint;
    
          u,v,w,new:array[0..120] of longint;
    
          vis:array[0..16] of boolean;
    
    procedure swap(var a,b:longint);
    
              var t:longint;begin t:=a;a:=b;b:=t;end;
    
    function  find(x:longint):longint;
    
              var t:longint;
    
              begin
    
              if father[x]=x then exit(x);
    
              t:=find(father[x]);
    
              father[x]:=t;
    
              exit(t);
    
              end;
    
    procedure union(x,y:longint);
    
              begin father[find(x)]:=find(y);end;
    
    function  check(bitset:longint;var sum:longint):boolean;
    
              var cur,h,t,i,j,temp:longint;
    
              begin sum:=0;
    
              fillchar(vis,sizeof(vis),false);
    
              for i:=0 to cnt do
    
                if(((bitset>>i)and 1)=1)
    
                  then inc(sum,w[new[i]]);
    
              for i:=0 to n-1 do
    
                if not vis[i]
    
                  then begin
    
                       h:=0;t:=1;Q[1]:=i;
    
                       vis[i]:=true;temp:=a[i];
    
                       while h<t do begin
    
                         inc(h);cur:=Q[h];
    
                         for j:=0 to n-1 do
    
                         if(not vis[j])and(map[cur][j]<>-1)and
    
                           (((bitset shr map[cur][j])and 1)=1)
    
                           then begin
    
                                inc(t);Q[t]:=j;
    
                                vis[j]:=true;
    
                                inc(temp,a[j]);
    
                                end;
    
                         end;
    
                       if temp<>0 then exit(false);
    
                       end;
    
              exit(true);
    
              end;
    
    begin
    
    readln(n,m);fall:=(1<<n)-1;
    
    ans:=inf;cnt:=-1;
    
    filldword(map,sizeof(map) shr 2, -1);
    
    for i:=0 to n-1 do
    
      begin
    
      read(A[i]);
    
      father[i]:=i;
    
      end;
    
    for i:=1 to m do
    
       begin
    
       readln(vi,ui,t);
    
       u[i-1]:=vi;
    
       v[i-1]:=ui;
    
       w[i-1]:=t;
    
       end;
    
    for i:=0 to m-2 do
    
      for j:=i to m-1 do
    
        if w[j]<w[i]
    
          then begin
    
               swap(u[i],u[j]);
    
               swap(v[i],v[j]);
    
               swap(w[i],w[j]);
    
               end;
    
    for i:=0 to m-1 do
    
      if find(v[i])<>find(u[i])
    
        then begin
    
             inc(cnt);new[cnt]:=i;
    
             map[v[i]][u[i]]:=cnt;
    
             map[u[i]][v[i]]:=cnt;
    
             union(v[i],u[i]);
    
             end;
    
    if(cnt=-1)
    
      then begin
    
           if check(0,temp)
    
             then writeln(0)
    
             else writeln('Impossible');
    
           end
    
      else begin
    
           for i:=0 to (1<<(cnt+1))-1 do
    
             if check(i,temp)
    
               then ans:=min(ans,temp);
    
           if ans<>inf
    
             then writeln(ans)
    
             else writeln('Impossible');
    
           end;
    
    end.

    C 圣主的考验

          知道是DP而不会做的感觉,无力啊。

  • 相关阅读:
    linux上实现jmeter分布式压力测试(转)
    The more,the better。
    DP_括号匹配序列问题
    MySQL基础语句
    大端模式和小端模式
    C++:bitset用法
    TCP三次握手和四次握手
    静态库与动态库
    DP_最长公共子序列/动规入门
    二维数组和指针
  • 原文地址:https://www.cnblogs.com/lijianlin1995/p/2753427.html
Copyright © 2011-2022 走看看