HDU 6046 hash (HASH, 2017 Multi-Univ Training Contest 2)
来源:互联网 发布:xperia x compact 知乎 编辑:程序博客网 时间:2024/06/05 21:12
Problem
f(x, y)
表示该矩阵的 x 行 j 列的数
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;}
提供
Idea
由于 A 矩阵过大,纵然想要先行获取其每位的数值,在时间复杂度内也是不允许的。
考虑将 B 矩阵按
将 A 矩阵严格划分为
则获取每个
对获取到的矩阵判断其是否与 B 矩阵完全相同即可(也可不必判断,由于 A 矩阵完全随机,故碰撞的概率很小)。
Code
#include<bits/stdc++.h>using namespace std;const int N = 1e6 + 10;const int HASH_SEED = 1999997;int T, ica = 1;unsigned long long num, g[HASH_SEED];char b[1010][1010];int b8[1010][1010], x[HASH_SEED], y[HASH_SEED];void HASH(int i, int j) { int hash = num % HASH_SEED; while(g[hash]) { if(++hash == HASH_SEED) hash = 0; } g[hash] = num; x[hash] = i; y[hash] = j;}inline unsigned sfr(unsigned h, unsigned x) { return h >> x; } int f(long long i, long long j) { long long 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; }bool jug(int x, int y) { if(x <= 0 || y <= 0) return false; for(int i=0;i<1000;i++) for(int j=0;j<1000;j++) if(f(x+i, y+j) != b[i+1][j+1]-'0') return false; return true;}bool solveHash(int i, int j) { num = 0; for(int ii=0;ii<8;ii++) for(int jj=0;jj<8;jj++) { num <<= 1; num += f(i+ii, j+jj); } int hash = num % HASH_SEED; while(g[hash]) { if(g[hash] == num) { printf("Case #%d :%d %d\n", ica++, i-x[hash]+1, j-y[hash]+1); return true; } if(++hash == HASH_SEED) hash = 0; } return false;}void solve() { for(int i=1;i<1000000;i+=1000) for(int j=1;j<1000000;j+=1000) if(solveHash(i, j) || solveHash(i+1000-7, j+1000-7)) return;}int main(){ scanf("%d", &T); while(ica <= T) { memset(g, 0, sizeof(g)); for(int i=1;i<=1000;i++) { scanf(" %s", b[i]+1); num = 0; for(int j=1;j<=7;j++) num<<=1, num += b[i][j]-'0'; for(int j=8;j<=1000;j++) { num<<=1, num+=b[i][j]-'0'; num %= 256; b8[i][j-7] = num; } } for(int i=1;i<=1000-7;i++) for(int j=1;j<=1000-7;j++) { num = 0; for(int k=0;k<8;k++) num<<=8, num += b8[i+k][j]; HASH(i, j); } solve(); }}
阅读全文
0 0
- HDU 6046 hash (HASH, 2017 Multi-Univ Training Contest 2)
- HDU 6058 Kanade's sum (链表, 2017 Multi-Univ Training Contest 3)
- HDU 6065 RXD, tree and sequence (LCA, 2017 Multi-Univ Training Contest 3)
- HDU 6071 Lazy Running (Dijstra, 2017 Multi-Univ Training Contest 4)
- HDU 6078 Wavel Sequence (dp + 树状数组, 2017 Multi-Univ Training Contest 4)
- HDU 6069 Counting Divisors (2017 Multi-Univ Training Contest 4)
- HDU 6070 Dirt Ratio (二分+线段树, 2017 Multi-Univ Training Contest 4)
- HDU 6073 Matching In Multiplication (拓扑+DFS, 2017 Multi-Univ Training Contest 4)
- HDU 6074 Phone Call (LCA+并查集, 2017 Multi-Univ Training Contest 4)
- HDU 6076 Security Check (DP, 2017 Multi-Univ Training Contest 4)
- HDU 6085 Rikka with Candies (bitset, 2017 Multi-Univ Training Contest 5)
- HDU 6090 Rikka with Graph (贪心+构造, 2017 Multi-Univ Training Contest 5)
- HDU 6072 Logical Chain (Biset+Kosaraju, 2017 Multi-Univ Training Contest 4)
- HDU 6086 Rikka with String (AC 自动机+状压 dp, 2017 Multi-Univ Training Contest 5)
- HDU 6093 Rikka with Number (2017 Multi-Univ Training Contest 5)
- HDU 6096 String (字典树, 2017 Multi-Univ Training Contest 6)
- HDU 6127 Hard challenge (极角排序+二分, 2017 Multi-Univ Training Contest 7)
- HDU 6124 Euler theorem (2017 Multi-Univ Training Contest 7)
- kali在高清屏幕下如何放大字体与图标
- 和客户沟通的总结
- Python学习之路Day2
- 打字游戏
- Android Studiod 的安装详情
- HDU 6046 hash (HASH, 2017 Multi-Univ Training Contest 2)
- netty学习五:websocket小demo
- 通达信行业、板块与自定义指数 (2015-09-01 17:58:00)
- sc2017新高二&高一模拟赛3 总结
- 关于跨域问题
- android使用Charles抓包https请求
- SpringBoot系列之一_入门
- 树莓派日常使用总结(随时更新)
- Androidstudio安装/更新之后新建项目会出现“building‘ 你的项目名’gradle project info”