• HDU 6046


    思路来自题解和一些博客

    最麻烦的是样例没啥用- -

    /*
    HDU 6046 - hash [ hash,鸽巢 ]  |  2017 Multi-University Training Contest 2
    题意:
    	给出一个1e3*1e3的矩阵以及 一个 生成1e6*1e6的矩阵的随机函数
    	在1e6*1e6的矩阵中找到1e3*1e3的矩阵的位置
    分析:
    	将1e3*1e3的矩阵每一个位置压入哈希表中,哈希值为其与之后63位所组成64位的值(不满64位就不压入)
    	由于 2^64 远大于 1e12 故可认为哈希值相同的是同一个位置
    	枚举大矩阵中的位置,若能在哈希表中找到这个位置的哈希值,则小矩阵头部的相对位置可以确定
    	但不需要枚举大矩阵中的每个位置,可以每隔1000行,隔900列枚举一个位置
    	这样根据鸽巢原理,枚举的这些位置至少有一个被小矩阵覆盖
    	
    	选隔900列而不是1000列的原因是 小矩阵每行最右端63个点没被压入哈希表,所以哈希表中的矩阵是 1000 * (1000-63)的
    */
    #include <bits/stdc++.h>
    using namespace std;
    #define LL unsigned long long
    const int N = 1e3+5;
    const int L = 1000;
    const int ZIP = 64;
    inline unsigned sfr(unsigned h, unsigned x) {
      return h >> x;
    }
    int f(LL i, LL j) {
        LL w = i * 1000000ll + j;
        int h = 0;
        for (int k = 0; k < 5; ++k) {
            h += (int) ((w >> (8 * k)) & 255);
            h += (h << 10);
            h ^= sfr(h, 6);
        }
        h += h << 3;
        h ^= sfr(h, 11);
        h += h << 15;
        return sfr(h, 27) & 1;
    }
    namespace HashMap{
        const int MOD = 1313131;
        struct Node {
            LL pos, val;
            int nxt;
        }node[N*N];
        int head[MOD], tot;
        void init() {
            memset(head, 0, sizeof(head));
            tot = 0;
        }
        void insert(LL v, LL p) {
            int t = v % MOD; tot++;
            node[tot].pos = p;
            node[tot].val = v;
            node[tot].nxt = head[t];
            head[t] = tot;
        }
        LL find(LL v) {
            for (int i = head[v%MOD]; i; i = node[i].nxt)
                if (node[i].val == v) return node[i].pos;
            return 0;
        }
    }
    char s[N];
    LL hs[N];
    int main()
    {
        int t; scanf("%d", &t);
        for (int tt = 1; tt <= t; tt++)
        {
            HashMap::init();
            for (int i = 1; i <= L; i++)
            {
                scanf("%s", s+1);
                hs[L+1] = 0;
                for (int j = L; j >= 1; j--)
                    hs[j] = hs[j+1]<<1|(s[j]-'0');
                for (int j = 1; j <= L-ZIP+1; j++)
                    HashMap::insert(hs[j], i*1024+j);
            }
            LL ans = 0; int x, y;
            for (int i = 1; i <= 1e6 && (!ans); i += 1000)
                for (int j = 1; j <= 1e6 && (!ans); j += 900)
                {
                    if (j+ZIP-1 > 1e6) continue;
                    LL val = 0;
                    for (int k = ZIP-1; k >= 0; k--)
                        val = val<<1|(f(i,j+k));
                    ans = HashMap::find(val);
                    if (ans != 0) x = i, y = j;
                }
            int px = x - ans / 1024 + 1, py = y - ans % 1024 + 1;
            printf("Case #%d :%d %d
    ", tt, px, py);
        }
    }
    

      

    我自倾杯,君且随意
  • 相关阅读:
    无题
    2G日产金士顿
    提防假TF卡,金士顿的识别 (有图)
    无题
    推荐小说
    开学了!
    测速软件
    提供《鬼吹灯》小说系列下载
    换博客了
    Kali_2020.01安装教程
  • 原文地址:https://www.cnblogs.com/nicetomeetu/p/7286724.html
Copyright © 2020-2023  润新知