字符串哈希题目总结

HDU1880

给出对应的字符串,需要建立相应的双向映射。也就是输入first串可以得出对应的second串,输入second串可以得出对应的first串

数据有100000 ,用map模拟爆内存。

使用 BKDRHash 哈希函数进行哈希

// BKDR Hash Function
unsigned int BKDRHash(char *str)
{
    unsigned int seed = 131; // 31 131 1313 13131 131313 etc..
    unsigned int hash = 0;
 
    while (*str)
    {
        hash = hash * seed + (*str++);
    }
 
    return (hash & 0x7FFFFFFF);
}
代码

#include 
#include 
#include 
#include 
using namespace std;
const int N = 100010;
const int H = 100007;
struct node{
    char que[25];
    char ans[85];
    int next;
};
node nodeA[N], nodeB[N];
int curA,curB;
int hashTableA[N] , hashTableB[N];
void initHash(){
    for(int i=0;i


POJ1743

意:有N(1 <= N <=20000)个音符的序列来表示一首乐曲,每个音符都是1..88范围内的整数,现在要找一个重复的主题。“主题”是整个音符序列的一个子串,它需要满足如下条件:

    1.长度至少为5个音符。

    2.在乐曲中重复出现。(可能经过转调,“转调”的意思是主题序列中每个音符都被加上或减去了同一个整数值)

    3.重复出现的同一主题不能有公共部分。

重复2次以上,不能有公共部分的最长子串。

后缀数组可解,

这里用到88进制取模进行哈希函数

想出这种方法的作者连接 http://blog.renren.com/share/283538506/12293487302/0


#include 
#include 
#include 
#include 
#include 
#include 

using namespace std;
const int maxh = 10007;
const int maxn  =  20010;
typedef long long ll;
typedef unsigned long long ull;
#define mem(a,x) memset(a,x,sizeof a)
struct HASHMAP{
    int head[maxh] , next[maxn] , size;
    ull  state[maxn];
    int f[maxn];
    void init(){
        size = 0;
        mem(head,-1);
    }
    int insert(ull val,int id){
        int h = val % maxh;
        for(int i=head[h]; i != -1; i = next[i]){
            if(val == state[i]) return f[i];
        }
        f[size] = id;
        state[size] = val;
        next[size] = head[h];
        head[h] = size++;
        return f[size  - 1];
    }
};
HASHMAP H;
const int SEED = 13331;
ull P[maxn];
ull S[maxn];
int A[maxn];
int n;
bool check(int x){
    H.init();
    for(int i=x;i>1;
            if(check(mid)){
                ans = mid;
                l = mid +1;
            }else
                r = mid -1;
        }
        if(ans < 4) ans = -1;
        ans++;
        printf("%d\n",ans);
    }
    return 0;
}






SCU4438 字符串hash ,好题

通过构造hash表,记录模式串的hash值,然后对主串按顺序遍历每个字符,并存入数组stack,并算出当前串的hash值,通过hash[i] - hash[i - len]*hashpow 算出当前子串是否与模式串hash值相等,相等就将数组stack中的下标回退len长度,实现删除匹配的串。

细节还有待推敲

代码

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define maxn 5000006
typedef unsigned long long ll;
ll hash = 100007;
ll hash_w;
ll hash_p [maxn];
ll hash_pow[maxn];

char p[maxn], w[maxn];
char stack[maxn];
int len ;
void init(){
    hash_pow[0] = 1;
    for(int i=1;i= len && hash_p[pos] -
        hash_p[pos - len] *hash_pow[len] == hash_w ){

       // cout<


HDU1280整数hash 水题

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define maxn 5000006
typedef unsigned long long ll;
#define mem(a,x) memset(a,x,sizeof a)
int arr[3333];
int vis[10010];
int main(){
    int n,m;
    while(scanf("%d%d",&n,&m) != EOF){
        mem(vis,0);
        for(int i=0;i=0;i--){
                if(!m)break;
                while(m && vis[i]){
                    if(isfirst)
                        printf("%d",i);
                    else
                        printf(" %d",i);
                    isfirst = false;
                    m--;
                    vis[i]--;
                }


        }
        puts("");

    }
    return 0;
}

HDU1496

a*x1^2+b*x2^2+c*x3^2+d*x4^2=0

给出这样一个式子,给出a,b,c,d.求有多少解, abcd范围 [-50,50] x1 - x4 [-100,100];

hash,四层循环改成二层循环,通过数组映射判断是否冲突,冲突就说明匹配,说明有解。另外特殊情况该优化的还要优化,否者会超时。

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
typedef unsigned long long ll;
#define mem(a,x) memset(a,x,sizeof a)
//-50*(10000) *2 = 1e 6;
const int maxn = 1e6 + 2;
int vis[2000010]; //2e6 + 10;
int main(){
    int a,b,c,d;

    while(scanf("%d%d%d%d", &a,&b,&c,&d) != EOF){
        if(a > 0 && b> 0 && c > 0 && d > 0){//没有这句就超市了
            puts("0");
            continue;
        }
        mem(vis,0);
        for(int i=1;i<=100;i++){
            for(int j=1;j<=100;j++){
                vis[a*i*i + b*j*j + maxn ] ++;
            }
        }
        int ans = 0;
        for(int i=1;i<=100;i++){
            for(int j=1;j<=100;j++){
                ans += vis[-(c*i*i + d*j*j)+maxn];
            }
        }
        // 每个i ,j都是可正 可负,2 * 2 * 2 * 2 == 16
        printf("%d\n",ans*16);
    }
    return 0;
}

ACDREAM 1726

给出N个数 和一个数 H ,从N个数中选择任意多个数,问有多少种选择使得选的数的和 等于H 。

N <=40 H <= 1e9

1e9需要哈希一下。

N = 40 折半之后哈希就可以了。

二分数据,数据减半后,时间复杂度 有 2 ^ 40 变为 2 ^ 20;

再用HASH判断是否满足

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
typedef long long ll;
#define mem(a,x) memset(a,x,sizeof a)
const int maxn = 1<<20; // 1048576
const int hash = 1000007; //开多大的hash

/*
3 1000010
next记录的是之前的head
head代表着数据在a数组中的位置。
head始终代表着头结点

*/
struct hashmap{
    ll a[maxn]; //映射入的数组
    int head[hash] , next[maxn],size;
    void init(){
        mem(head,-1);
        size = 0;
    }
    /*
    取模相同的数,存入a中之后,可以通过next遍历找到head进而找到对应a[i];
    实现了取模相同的数放到邻接表里一样的查询。
    */
    bool find(ll val){ //查找一个元素是否在hash表中
        int tmp = (val % hash + hash) % hash;
        for(int i=head[tmp]; i != -1;i = next[i]){
            if(val == a[i]) return true;
        }
        return false;
    }
    void add(ll val){ // 添加元素到hash表
        int tmp = (val % hash + hash) %hash;
        if(find(val)) return ;
        a[size] = val;
        next[size] = head[tmp];
        head[tmp] = size ++;
    }
}h1;
int n,m,num[55];

int main(){
//
//    h1.init();
//    h1.add(3);
//    h1.add(4);
//    h1.add(5);
//    h1.add(6);
//    h1.add(1000010);
//    h1.add(2000017);

    while(~scanf("%d%d",&n,&m)){
        h1.init();
        for(int i=0;i m) continue;
            h1.add(sum);
        }
        int tt = n - t; //枚举剩下的数
        int flag = 0;
        for(int i=0;i<(1< m) continue;
            if(h1.find(m - sum)){
                flag = 1; break;
            }
        }
        if(flag)
            printf("Yes\n");
        else
            printf("No\n");
    }
    return 0;
}


你可能感兴趣的:(字符串哈希题目总结)