第一篇博客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)脑残错误:

  1. for(int i=1;i<=n;i++)
  2. 71 {
  3. 73 for(int j=1;j<=k;j++)
  4. 74 {
  5. 75 num[i][j]-=num[i][1];//天真地以为这样就减去第一列了,当j=1执行后,num[i][1]已经 等于0了。。。还傻fufu调了半天(逃。。。。)
  6. 77 }
  7. 78 }
  1. 1 #include<iostream>
  2. 2 #include<cstdio>
  3. 3 #include<cstring>
  4. 4 #include<cstring>
  5. 5 #include<algorithm>
  6. 6 using namespace std;
  7. 7 const int mod=1000007;
  8. 8 const int maxn=1000009;
  9. 9 int n,k,cnt;
  10. 10 int num[1000100][31],head[1000100];
  11. 11 struct node
  12. 12 {
  13. 13 int num[31];
  14. 14 int next;
  15. 15 int p;
  16. 16 }edge[maxn];
  17. 17 void ins(int *num,int h,int p)
  18. 18 {
  19. 19 for(int i=1;i<=30;i++)
  20. 20 edge[cnt].num[i]=num[i];
  21. 21 edge[cnt].p=p;
  22. 22 edge[cnt].next=head[h];
  23. 23 head[h]=cnt++;
  24. 24 }
  25. 25 bool cmp(int *num1,int *num2)
  26. 26 {
  27. 27 for(int i=1;i<=k;i++)
  28. 28 if(num1[i]!=num2[i]) return 0;
  29. 29 return 1;
  30. 30 }
  31. 31 int search(int *num,int h)
  32. 32 {
  33. 33 int flag=0,ans=0;
  34. 34 for(int i=head[h];i!=-1;i=edge[i].next)
  35. 35 {
  36. 36 if(cmp(num,edge[i].num))
  37. 37 {
  38. 38 ans=edge[i].p;            //这里,不要马上返回
  39. 39 }
  40. 40 //return edge[i].p;
  41. 41 }
  42. 42 return ans;
  43. 43 }
  44. 44 int main()
  45. 45 {
  46. 46 int flag=0;
  47. 47 memset(head,-1,sizeof(head));
  48. 48 scanf("%d%d",&n,&k);
  49. 49 for(int i=1;i<=n;i++)
  50. 50 {
  51. 51 int x;
  52. 52 scanf("%d",&x);
  53. 53 for(int j=1;j<=k;j++)
  54. 54 {
  55. 55 num[i][j]=x%2;
  56. 56 x/=2;
  57. 57 }
  58. 58 }
  59. 59 for(int i=2;i<=n;i++)
  60. 60 {
  61. 61 for(int j=1;j<=k;j++)
  62. 62 num[i][j]+=num[i-1][j];
  63. 63 }
  64. 64 /*for(int i=1;i<=n;i++)
  65. 65 {
  66. 66 for(int j=1;j<=k;j++)cout<<num[i][j];
  67. 67 cout<<endl;
  68. 68 }*/
  69. 69 int ans=0;
  70. 70 for(int i=1;i<=n;i++)
  71. 71 {
  72. 72 int t=num[i][k];
  73. 73 for(int j=1;j<=k;j++)
  74. 74 {
  75. 75 num[i][j]-=t;
  76. 76 //if(num[i][j]<0) num[i][j]=-num[i][j];
  77. 77 }
  78. 78 }
  79. 79 /*for(int i=1;i<=n;i++)
  80. 80 {
  81. 81
  82. 82 for(int j=1;j<=k;j++)
  83. 83 cout<<num[i][j];
  84. 84 cout<<endl;
  85. 85 }*/
  86. 86 for(int i=1;i<=n;i++)
  87. 87 {
  88. 88 int base=0;
  89. 89 for(int j=1;j<=k;j++)
  90. 90 {
  91. 91 base+=num[i][j];
  92. 92 base*=10;
  93. 93 base%=mod;
  94. 94 //cout<<base<<endl;
  95. 95 }
  96. 96 if(base<0) base=-base;
  97. 97 int tmp=search(num[i],base);
  98. 98 if(tmp>0)
  99. 99 {
  100. 100 int t=abs(tmp-i);
  101. 101 if(t>ans)
  102. 102 {
  103. 103 //cout<<tmp<<" "<<i<<endl;
  104. 104 ans=t;
  105. 105 }
  106. 106 }
  107. 107 if(base==0)
  108. 108 {
  109. 109 ans=max(i,ans);
  110. 110 }
  111. 111 ins(num[i],base,i);
  112. 112 }
  113. 113 printf("%d\n",ans);
  114. 114 return 0;
  115. 115 }

 

版权声明:本文为codeoosacm原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/codeoosacm/p/9800658.html