zoukankan      html  css  js  c++  java
  • POJ3274(哈希)

    第一篇博客emmm

    根据kuangbin   dalao的poj刷题指南做的

    一道不是很简单的哈希题目

    题意是求特征之和相同的第i头牛到第j头牛的max(j-i)

    一开始是没有思路的,苦思冥想半天

    然后(看了题解以后)手推公式:

    num[i][1]+...+num[j][1]=num[i][2]+....+num[j][2]=num[i][k]+...+num[j][k];

    ①num[i][1]+...+num[j][1]=num[i][k]+...+num[j][k];

    ②sum[i][k]=sum[i-1][k]+num[i][k];

    ①,②=>sum[j][k]-sum[i][k]=sum[j][0]-sum[i][0];

    =>sum[j][k]-sum[j][0]=sum[i][k]-sum[i][0];

    所以对于sum矩阵,每个元素减去第一列

    然后求sum矩阵相同的行的最大距离即可

    二进制转化成k进制作为哈希值。

    自己踩的坑如下:

    (1)mod余数越界,调了好久

    (2)矩阵每列元素减去第一列元素会导致最后的hash值可能是负的,要用abs把它变成正数

    (3)search的时候不要找到就直接返回j值,要找到最后一个满足cmp的j值,因为前向星是倒着存的,而我们要的是最靠前的j值,越靠前,对于当前i值来说,距离越大,所以最晚出现的值是符合条件的

    (4)脑残错误:

    for(int i=1;i<=n;i++)
     71     {
     73         for(int j=1;j<=k;j++)
     74         {
     75             num[i][j]-=num[i][1];//天真地以为这样就减去第一列了,当j=1执行后,num[i][1]已经 等于0了。。。还傻fufu调了半天(逃。。。。)
     77         }
     78     }
      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<cstring>
      5 #include<algorithm>
      6 using namespace std;
      7 const int mod=1000007;
      8 const int maxn=1000009;
      9 int n,k,cnt;
     10 int num[1000100][31],head[1000100];
     11 struct node
     12 {
     13     int num[31];
     14     int next;
     15     int p;
     16 }edge[maxn];
     17 void ins(int *num,int h,int p)
     18 {
     19     for(int i=1;i<=30;i++)
     20         edge[cnt].num[i]=num[i];
     21     edge[cnt].p=p;
     22     edge[cnt].next=head[h];
     23     head[h]=cnt++;
     24 }
     25 bool cmp(int *num1,int *num2)
     26 {
     27     for(int i=1;i<=k;i++)
     28     if(num1[i]!=num2[i]) return 0;
     29     return 1;
     30 }
     31 int search(int *num,int h)
     32 {
     33     int flag=0,ans=0;
     34     for(int i=head[h];i!=-1;i=edge[i].next)
     35     {
     36         if(cmp(num,edge[i].num))
     37         {
     38             ans=edge[i].p;            //这里,不要马上返回
     39         }
     40             //return edge[i].p;
     41     }
     42     return ans;
     43 }
     44 int main()
     45 {
     46     int flag=0;
     47     memset(head,-1,sizeof(head));
     48     scanf("%d%d",&n,&k);
     49     for(int i=1;i<=n;i++)
     50     {
     51         int x;
     52         scanf("%d",&x);
     53         for(int j=1;j<=k;j++)
     54         {
     55             num[i][j]=x%2;
     56             x/=2;
     57         }
     58     }
     59     for(int i=2;i<=n;i++)
     60     {
     61         for(int j=1;j<=k;j++)
     62             num[i][j]+=num[i-1][j];
     63     }
     64     /*for(int i=1;i<=n;i++)
     65     {
     66         for(int j=1;j<=k;j++)cout<<num[i][j];
     67         cout<<endl;
     68     }*/
     69     int ans=0;
     70     for(int i=1;i<=n;i++)
     71     {
     72         int t=num[i][k];
     73         for(int j=1;j<=k;j++)
     74         {
     75             num[i][j]-=t;
     76             //if(num[i][j]<0) num[i][j]=-num[i][j];
     77         }
     78     }
     79     /*for(int i=1;i<=n;i++)
     80     {
     81 
     82         for(int j=1;j<=k;j++)
     83             cout<<num[i][j];
     84         cout<<endl;
     85     }*/
     86     for(int i=1;i<=n;i++)
     87     {
     88         int base=0;
     89         for(int j=1;j<=k;j++)
     90         {
     91             base+=num[i][j];
     92             base*=10;
     93             base%=mod;
     94             //cout<<base<<endl;
     95         }
     96         if(base<0) base=-base;
     97         int tmp=search(num[i],base);
     98         if(tmp>0)
     99         {
    100             int t=abs(tmp-i);
    101             if(t>ans)
    102             {
    103                 //cout<<tmp<<" "<<i<<endl;
    104                 ans=t;
    105             }
    106         }
    107         if(base==0)
    108         {
    109             ans=max(i,ans);
    110         }
    111         ins(num[i],base,i);
    112     }
    113     printf("%d
    ",ans);
    114     return 0;
    115 }
  • 相关阅读:
    北风网第一季度菜单6
    北风网微信第一季菜单5
    win7卸载打印机驱动
    myeclipse 10激活,本人已测试过可行
    北风网视频菜单4
    Code Project精彩系列(1)
    Code Project精彩系列(1)
    Code Project精彩系列(1)
    实现Windows和Linux之间的文件共享
    实现Windows和Linux之间的文件共享
  • 原文地址:https://www.cnblogs.com/codeoosacm/p/9800658.html
Copyright © 2011-2022 走看看