随笔分类 - Hash-散列
非比较查找
摘要:题意:给定一个N*N的网格,现在M组操作,一种操作时改变网格上的某个单点的权值,另外一种操作是求到一点曼哈顿距离为小于等于k的所有的权值和,初始化网格所有点的权值为0。解法:这题如果没有那些特定的条件,那么就是一个纯净的二维树状数组。对于题目中的要求需要解决的两个问题是:如何将题目中的曼哈顿距离转化为规则的矩形,以及如何避免开辟一个巨大的数组。1.如何转化为矩形问题,这里处理的方法就是把所有的点都旋转45度,需要一个2N*2N的数组数组才能容下坐标转换之后的图,坐标的转化方式为nx = x - y + N, ny = x + y - 1。可以这样看,转化之后的同行相邻两列的坐标差为(-1, 1
阅读全文
摘要:搜索+剪枝#include <cstdlib>#include <cstring>#include <cstdio>#include <algorithm>#include <iostream>#define MAXN 5005using namespace std;/*题意: 给定一个行数和列数固定的网格,再给定若干个点,这些点是使用矩形上网格线交叉点的 坐标来唯一确定的R行C列的网格,左上角的坐标为(1,1)右下角的坐标为(R,C),问给定的 这些点能够组成最长可能路径是多长. 路径的定义的如下的:由若干连续且间隔相等的 点组成,
阅读全文
摘要:详见代码:#include <cstring>#include <cstdlib>#include <cstdio>#include <iostream>#define T 31LLUusing namespace std;typedef unsigned long long Int64;// 给定一个字符串,现在在这个串上进行一系列的动态操作// 难点是在这些动态的修改的过程中,问任意一段是否为回文串 // 思路是以某种方法来判定一个串是否相等,我们很容易想到字// 符串的hash处理,对就是插值取模,解决了字符串比较的问题// 选择插值取模的
阅读全文
摘要:这题主要是要将两个串的比较进行优化,不能够每次都从起始位置进行匹配。这里用到了线段树进行优化,将每段区间的hash值进行更新和维护,通过找某一点的有连续段最长相同串即可。代码如下:#include <cstdlib>#include <cstring>#include <cstdio>#include <algorithm>#define MOD 100000003#define T 29LLusing namespace std;typedef unsigned int Int64;// 这里建立棵线段树记录某一短区间的hash值 char s
阅读全文
摘要:这题就是一个数据量大点的a+b+c+d+e = 0的判定,可以用哈希表来做,也可以用来个有序表来寻找解。时间复杂度前者接近O(n^3),后者则为O(N^3).代码如下:哈希表:#include<iostream>#include<map>#define MOD 1000003LLusing namespace std;typedef long long LL;const int N = 205;LL a[6][N];int head[1000005], idx;struct Node{ LL v; int next; }e[40005];void add(LL key)
阅读全文
摘要:这题简单说就是求矩形的面积并,线段树?只有20个矩形,我们可以用容斥来做。但是这个有个比较麻烦的地方就是要求出任意组合情况下的面积并,试过几次每次进行求解的写法都一一超时了。这里选择在dfs的时候直接枚举题目将询问的状态,只要当前状态是其子集的话,就直接加到上面。最后M次询问就能够在O(1)的时间内完成了。296MS水过了。代码如下:#include <cstring>#include <cstdlib>#include <cstdio>#include <algorithm>#define INF 10000using namespace st
阅读全文
摘要:该题题意是给定一个音乐串,要求最长的主题串满足可以找到两个这样的串,在对方的每一位添加一个数字 两个串互相不能够有重叠有是多项式插值取模的hash的应用代码如下:#include <cstdlib>#include <cstring>#include <cstdio>#define T 99991#define MAXN 20000#define MOD 3001using namespace std;typedef unsigned long long UInt64;struct Node{ UInt64 key; int begin, end, next
阅读全文
摘要:这题的题意是给定N个串,某个串的子串在超过一半的串存在的话,那么这个串就是可取的,问满足这样的子串的最长长度是多少,如果有多个的话,按字典序输出。这题我是用hash过的。大体步骤是这样的,首先保留最长串的长度,然后二分0-MAXNLEN得到答案,那么这里重点就是如何去写这个判定函数。二分里面只会传递一个参数那就是长度K,根据这个长度我们把所有的串都拆成长度为K的子串,这里有个优化就是使用一种hash规则能够在得到1 - N的hash的时候计算出2 - N+1的hash值,那么这里用到了经典的多项式插值取模的方法:假设有一个字符串a[0],a[1],a[2],a[4],取长度为3的子串的时候,第
阅读全文
摘要:这题用hash表做有点无病呻吟了,因为用map更快更简单。把字符串按每一位乘以相应的位置,再进行hash操作。这题还做的时候还遇到一个问题,在进行字符串复制的时候,由于直接sizeof(in)由于in在这个函数里面覆盖了全局的in所以in是一个指针变量,所以并不是15而是4,每次只赋值4个字节,肯定是错了点。代码如下:#include <cstring>#include <cstdio>#include <cstdlib>#define MOD 2000003using namespace std;char s[50], in[15], out[15];in
阅读全文
摘要:不得不说上次看得的这句话是多么对,再差的Hash表都比map好,hash表的查找速度可不是logn能够比的。首先将5个部分拆成2+3,我们选取2的部分进行hash,然后再进行3重for循环。动态申请内存还是比不上静态的啊。代码如下:动态申请内存:#include <cstdio>#include <cstring>#include <cstdlib>#define MOD 20003using namespace std;int rec[105];struct Node{ int x; Node *next;}e[20003];void Hash(int k
阅读全文
摘要:这题直接两个for循环直接TLE,所以这里要先进行一次哈希,然后一次排序,这样只要比较相邻的并且hash值相同的两个串即可。代码如下:#include <cstdlib>#include <cstring>#include <cstdio>#include <algorithm>#define MOD 100000007using namespace std;int N, a[6];struct Node{ int a[6], sum; bool operator < (Node t) const { return sum < t.s
阅读全文
摘要:http://acm.hdu.edu.cn/showproblem.php?pid=3833 做这题还真是纠结啊,有很多小地方要注意。前面没有看清题义,题中给的数字是一个1-N的排列。 这题是这么做的,首先将每个数字的顺序通过数组记录起来,然后再根据 2*p[i2] = p[i1] + p[i3]进行暴力搜索。 搜索过程中要特别注意范围的选定,由于 p[i2] 是中间的一个数,所以其范围为 2 <= p[i2] <= N-1 ,而 p[i1] < p[i2] && p[i2] > p[i3];同时应该记得有范围 1 <= p[i1] <= N
阅读全文
摘要:题目要求 x^2 + y^2+ z^2 = N,把 1^2 到 100^2 的平方数保留一份,并且标记一份,后面就使用两重循环就可以了。 代码如下:#include <cstring>#include <cstdlib>#include <cstdio>using namespace std;char hash[100005][2];int rec[105];int main(){ for( int i= 1; i<= 100; ++i ) { rec[i]= i* i; hash[rec[i]][0]= 1; hash[rec[i]][1]= i;
阅读全文
摘要:SORT AGAIN Time Limit: 2000/1000 MS (Java/Others)Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1395Accepted Submission(s): 448Problem Description给你N个整数,x1,x2...xn,任取两个整数组合得到|xi-xj|,(0<i,j<=N,i!=j)。现在请你计算第K大的组合数是哪个(一个组合数为第K大是指有K-1个不同的组合数小于它)。Input输入数据首先包含一个正整数C,表示包含C组测试用例.每组测试数
阅读全文
摘要:排列2Time Limit: 1000/1000 MS (Java/Others)Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1438Accepted Submission(s): 535Problem DescriptionRay又对数字的列产生了兴趣:现有四张卡片,用这四张卡片能排列出很多不同的4位数,要求按从小到大的顺序输出这些4位数。Input每组数据占一行,代表四张卡片上的数字(0<=数字<=9),如果四张卡片都是0,则输入结束。Output对每组卡片按从小到大的顺序输出所有能由这四张卡片组成
阅读全文
摘要:Flying to the MarsTime Limit: 5000/1000 MS (Java/Others)Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 3572Accepted Submission(s): 1129Problem DescriptionIn the year 8888, the Earth is ruled by the PPF Empire . As the population growing , PPF needs to find more land for the newborns .
阅读全文
摘要:Equations Problem DescriptionConsider equations having the following form: a*x1^2+b*x2^2+c*x3^2+d*x4^2=0a, b, c, d are integers from the interval [-50,50] and any of them cannot be 0.It is consider a solution a system ( x1,x2,x3,x4 ) that verifies the equation, xi is an integer from [-100,100] and .
阅读全文
摘要:Counting SquaresTime Limit: 2000/1000 MS (Java/Others)Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 405Accepted Submission(s): 212Problem DescriptionYour input is a series of rectangles, one per line. Each rectangle is specified as two points(X,Y) that specify the opposite corners of
阅读全文
摘要:前m大的数Time Limit: 2000/1000 MS (Java/Others)Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 3103Accepted Submission(s): 1096Problem Description还记得Gardon给小希布置的那个作业么?(上次比赛的1005)其实小希已经找回了原来的那张数表,现在她想确认一下她的答案是否正确,但是整个的答案是很庞大的表,小希只想让你把答案中最大的M个数告诉她就可以了。给定一个包含N(N<=3000)个正整数的序列,每个数不超过5000,对它
阅读全文