zoukankan      html  css  js  c++  java
  • POJ1743 Musical Theme 哈希

    该题题意是给定一个音乐串,要求最长的主题串满足
    可以找到两个这样的串,在对方的每一位添加一个数字
    两个串互相不能够有重叠

    有是多项式插值取模的hash的应用

    代码如下:

    #include <cstdlib>
    #include <cstring>
    #include <cstdio>
    #define T 99991
    #define MAXN 20000
    #define MOD 3001
    using namespace std;
    
    typedef unsigned long long UInt64;
    
    struct Node
    {
        UInt64 key;
        int begin, end, next;
    }e[3000000];
    
    int N, seq[MAXN+5], diff[MAXN+5], head[MOD], idx;
    
    UInt64 POW[(MAXN>>1)+5];
    
    void getint(int &t)
    {
        char c;
        while (c = getchar(), c < '0' || c > '9');
        t = c - '0';
        while (c = getchar(), c >= '0' && c <= '9') {
            t = t * 10 + c - '0';
        }
    }
    
    int Hash(UInt64 key, int begin, int end)
    { // 这里应用贪心思想,如果前面有一个提前完成的主题,一定取前面的主题 
        int Rkey = key % MOD, flag = 0;
        for (int i = head[Rkey]; i != -1; i = e[i].next) {
            if (key == e[i].key) {
                flag = 1;
                if (begin > e[i].end) {
                    return true;
                }
            }
        }
        if (!flag) {
            ++idx;
            e[idx].key = key, e[idx].begin = begin;
            e[idx].end = end, e[idx].next = head[Rkey];
            head[Rkey] = idx;
        }
        return false;
    } 
    
    bool Accept(int k)
    {
        UInt64 key = 0;
        idx = -1;
        memset(head, 0xff, sizeof (head));
        for (int i = 1; i <= k; ++i) {
            key = key * T + diff[i];
        }
        if (Hash(key, 0, k)) {
            return true;
        }
        for (int i = 2; i <= N-k+1; ++i) {
            key -= diff[i-1] * POW[k-1];
            key = key * T + diff[i+k-1];
            if (Hash(key, i-1, i+k-1)) {
                // 这里的begin和end要映射到原数组中
                return true;
            }
        }
        return false;
    }
    
    int bsearch(int l, int r)
    {
        int mid;
        while (l <= r) {
            mid = (l+r) >> 1;
            if (Accept(mid)) {
                l = mid + 1;
            }
            else {
                r = mid - 1;
            }
        } 
        return r;
    }
    
    int main()
    {
        POW[0] = 1;
        int ans; 
        for (int i = 1; i <= 10000; ++i) {
            POW[i] = POW[i-1] * T;
        }
        while (scanf("%d", &N), N) {
            for (int i = 0; i < N; ++i) {
                getint(seq[i]);
            //    scanf("%d", &seq[i]);
            }
            N -= 1;
            for (int i = 1; i <= N; ++i) {
                diff[i] = seq[i] - seq[i-1] + 203;
            }
            if (N >= 9) {
                ans = bsearch(4, N>>1);
                if (ans >= 4) {
                    printf("%d\n", ans+1);
                }
                else {
                    puts("0");
                }
            }
            else {
                puts("0");
            }
        }
        return 0;    
    } 
  • 相关阅读:
    Android音频(7)——项目实战——耳麦插拔
    Android音频(6)——音频系统分析
    Android音频(5)——框架中的概念和涉及的文件
    Android音频(4)——音频驱动实战
    Android音频(3)——ALSA声卡驱动——DAPM
    Android音频(2)——ALSA声卡驱动——ASoC
    Mvc中Session导致action不异步的问题
    RabbitMQ 声明Queue时的参数们的Power
    RabbitMQ 实现RPC
    RabbitMQ Topic exchange
  • 原文地址:https://www.cnblogs.com/Lyush/p/2598426.html
Copyright © 2011-2022 走看看