• poj3274


    很不错的hash

    优化有两个方面:1.根据题目换一个更优化的算法 2.在算法运行过程中优化

    这题除了暴力好像没别的办法了吧?

    但是暴力也是有策略的!

    到第i只牛特征为j的总数为sum[i,j];

    找到最大的区间(l,r]使得sum[r,1]-sum[l,1]=sum[r,2]-sum[l,2]…=sum[r,k]-sum[l,k]

    整理就得sum[r,1]-sum[r,2]=sum[l,1]-sum[l,2] sum[r,1]-sum[r,3]=sum[r,1]-sum[r,3]……

    于是做到每只牛的时候,我们就能得到一个序列。满足条件就是两个序列相等,

    怎么快速判断序列:hash!得解!

     1 type link=^node;
     2      node=record
     3        data:longint;
     4        next:link;
     5      end;
     6 const key=200007;
     7 var hash:array[0..200010] of link;
     8     sum:array[0..40] of longint;
     9     num:array[0..100010,0..40] of longint;
    10     ans,n,k,x,j,i,s:longint;
    11 function max(a,b:longint):longint;
    12   begin
    13     if a>b then exit(a) else exit(b);
    14   end;
    15 
    16 function allsame(x,y:longint):boolean;  //注意可能出现hash值相同但序列不同
    17   var i:longint;
    18   begin
    19     allsame:=true;
    20     for i:=1 to k do
    21       if num[x,i]<>num[y,i] then exit(false);
    22   end;
    23 
    24 procedure add(x,y:longint);
    25   var p:link;
    26   begin
    27     new(p);
    28     p^.data:=y;
    29     p^.next:=hash[x];
    30     hash[x]:=p;
    31   end;
    32 
    33 procedure push(x,i:longint);
    34   var p:link;
    35   begin
    36     if hash[x]=nil then add(x,i)
    37     else begin
    38       p:=hash[x];
    39       while p<>nil do
    40       begin
    41         if allsame(p^.data,i) then
    42         begin
    43           ans:=max(ans,i-p^.data);  //如果相同,那么当前序列就无需入hash
    44           exit;
    45         end;
    46         p:=p^.next;
    47       end;
    48       add(x,i);  //拉链法解决冲突
    49     end;
    50   end;
    51 
    52 begin
    53   readln(n,k);
    54   add(0,0);
    55   for i:=1 to n do
    56   begin
    57     readln(x);
    58     j:=0;
    59     while x<>0 do
    60     begin
    61       j:=j+1;
    62       sum[j]:=sum[j]+x mod 2;
    63       x:=x shr 1;
    64     end;
    65     s:=0;
    66     for j:=1 to k do
    67     begin
    68       num[i,j]:=sum[1]-sum[j];   //生成序列
    69       s:=(s+sqr(num[i,j])*j mod key) mod key ; //很奇怪的hash……
    70     end;
    71     push(s,i);  //hash值都不同那么序列一定不同
    72   end;
    73   writeln(ans);
    74 end.
    View Code

    判断两个序列是否相同,hash是个好方法!

  • 相关阅读:
    ICL7135的C程序
    数组属性的习题、Arrays工具、二维数组
    上传文件js端处理
    Java常见的系统路径与获取方法
    java 文件流的处理 文件打包成zip
    JAVA根据URL网址获取输入流
    nginx安装教程
    jackson 实体转json json字符串转实体
    java 对象重写tostring
    java 将文件流和文件名称转换为文件
  • 原文地址:https://www.cnblogs.com/phile/p/4473286.html
Copyright © 2020-2023  润新知