• [vijos P1112] 小胖的奇偶


    第一次看到这题怎么也不会想到是并查集题目…星期五第一次看到这题,到今天做出来,实在是废了好多功夫。看了很多人的解题都有same和diff数组,我也写了,后来发现不对啊两个数组的话find函数怎么写呢?hash也很久没写了,导致自己测试的时候有两个点没过是因为hash弄错了。

    我的程序里f[x]= same[x] (x<=max)

                       = diff[x-max] (x>max)

    总算,最后还是通过了。又是一道想不到思路就写不出的题。据说这题和食物链很像,那么食物链就是我的下一个目标~总感觉并查集是有点抽象的,我还没想到它怎么和树形结构具体联系起来。

    BTW,vijos的数据挺弱的…

    program vijos_p1112;
    const BLOCK=40000;
    var hash,f:array[0..80000] of longint;
        n,m,i,a,b,t:longint;
        s:string;
    function haha(x:longint):longint;
    var t:longint;
    begin
      t:=x mod 32567;
      while (hash[t]<>-1) and (hash[t]<>x) do inc(t);
      exit(t);
    end;
    
    function find(x:longint):longint;
    begin
      if f[x]=x then exit(x) else exit(find(f[x]));
    end;
    
    procedure union(x,y:longint);
    var fx,fy:longint;
    begin
      fx:=find(x);
      fy:=find(y);
      if fx<>fy then f[fx]:=fy;
    end;
    
    begin
      readln(n);
      readln(m);
      if m=0 then
        begin
          writeln(0);
          halt;
        end;
      for i:=1 to 40000 do
        begin
          f[i]:=i;
          hash[i]:=-1;
        end;
      for i:=1 to m do
        begin
          readln(s);
          t:=pos(' ',s);
          val(copy(s,1,t-1),a);
          delete(s,1,t);
          t:=pos(' ',s);
          val(copy(s,1,t-1),b);
          delete(s,1,t);
          if s='even' then
            begin
              if find(haha(a-1))=find(haha(b+BLOCK)) then
                begin
                  writeln(i-1);
                  halt;
                end
              else
                begin
                  union(haha(a-1),haha(b));
                  union(haha(a-1+BLOCK),haha(b+BLOCK));
                end;
            end
          else
            begin
              if find(haha(a-1))=find(haha(b)) then
                begin
                  writeln(i-1);
                  halt;
                end
              else
                begin
                  union(haha(a-1),haha(b+BLOCK));
                  union(haha(a-1+BLOCK),haha(b));
                end;
            end;
        end;
      writeln(m);
    end.
    小胖的奇偶

    测试数据 #0: Accepted, time = 0 ms, mem = 1360 KiB, score = 10
    测试数据 #1: Accepted, time = 0 ms, mem = 1360 KiB, score = 10
    测试数据 #2: Accepted, time = 0 ms, mem = 1360 KiB, score = 10
    测试数据 #3: Accepted, time = 0 ms, mem = 1364 KiB, score = 10
    测试数据 #4: Accepted, time = 15 ms, mem = 1364 KiB, score = 10
    测试数据 #5: Accepted, time = 15 ms, mem = 1360 KiB, score = 10
    测试数据 #6: Accepted, time = 15 ms, mem = 1368 KiB, score = 10
    测试数据 #7: Accepted, time = 0 ms, mem = 1364 KiB, score = 10
    测试数据 #8: Accepted, time = 15 ms, mem = 1364 KiB, score = 10
    测试数据 #9: Accepted, time = 0 ms, mem = 1364 KiB, score = 10

    话说把奇怪的写失败了的东西也扔上来吧0 0

    program vijos_p1112;
    var same,diff:array[1..10000] of integer;
        haha,f:array[1..20000] of longint;
        n,m,i,j,a,b,t:longint;
        s:string;
    function hash(x:longint):longint;
    var t:longint;
    begin
      t:=((x mod 19999)*(x mod 19999)) mod 19999+1;
      while (haha[t]<>0) and (haha[t]<>x) do
        inc(t);
      haha[t]:=x;
      exit(t);
    end;
    
    {function find(x:longint):longint;   same &diff de find ya fen kai
    begin
      if x=f[x] then exit(x) else exit(find(f[x]));
    end; }
    
    function sfind(x:longint):longint;
    begin
      if hash(x)=same[hash(x)] then exit(hash(x)) else exit(sfind(same[hash(x)]));
    end;
    
    function dfind(x:longint):longint;
    begin
      if hash(x)=diff[hash(x)] then exit(hash(x)) else exit(dfind(diff[hash(x)]));
    end;
    
    procedure union(x,y:longint;a,b:word);
    var fx,fy:longint;
    begin
      if a=1 then fx:=sfind(x) else fx:=dfind(x);
      if b=1 then fy:=sfind(y) else fy:=dfind(y);
      if (fx<>fy) then f[fx]:=fy;
    end;
    
    function pd:boolean;
    var buzhidao:integer;
    begin
      if s='even' then
        begin
          if sfind(same[hash(a-1)])=dfind(diff[hash(b)]) then
            begin
              writeln(i-1);
              halt;
            end;
        end
      else
        begin
          if sfind(same[hash(a-1)])=sfind(same[hash(b)]) then
            begin
              writeln(i-1);
              halt;
            end;
        end;
      pd:=true;
    end;
    
    begin
      readln(n);
      readln(m);
      for i:=1 to m*2 do
        begin
          same[i]:=i;
          diff[i]:=i+32000;
        end;
      for i:=1 to m do
        begin
          readln(s);
          t:=pos(' ',s);
          val(copy(s,1,t-1),a);
          delete(s,1,t);
          t:=pos(' ',s);
          val(copy(s,1,t-1),b);
          delete(s,1,t);
          if s='even' then
            begin
              if pd then
                begin
                  union(same[hash(a-1)],same[hash(b)],1,1);
                  union(diff[hash(a-1)],diff[hash(b)],2,2);
                end;
            end
          else
            begin
              if pd then
                begin
                  union(same[hash(a-1)],diff[hash(b)],1,2);
                  union(diff[hash(a-1)],same[hash(b)],2,1);
                end;
            end;
        end;
    end.
    小胖的奇偶-demo
  • 相关阅读:
    windows 安装 ELK(Elasticsearch,Logstash,kibana)
    NSSM 将程序封装成服务软件
    面试-双向链表
    mySql 事务,游标以及循环
    SQL 事务
    C# Windows 服务
    MVC 中ajax 调用Webservice 或WCF 问题
    js prototype
    计算一个数等于其它数相加的所有可能 如: 5 =1+4 ,1+3+1,2+3,2+2+1,1+1+1+1+1,1+1+1+2
    冒泡排序,选择排序,快速排序
  • 原文地址:https://www.cnblogs.com/Sky-Grey/p/3516135.html
Copyright © 2020-2023  润新知