题意:
      给你一个矩阵,上面只有*和0(最大1000*1000),然后有t(最大100)组询问,每组询问给你一个小矩阵(最大50*50),问这t个矩阵中有多少个是在大矩阵中出现的。

思路:

      这个题目做的有点蛋疼,说下我的第一个思路,我的想法是把所有的数据都按照行去压缩成longlong的,因为最大50位<64位 可以直接每行都压缩了,每个p*q的小矩阵就变成p个longlong的数字了,然后在把大矩阵同样处理,可以得到n*(m-q+1)个longlong的数字,然后就直接暴力的去KMP匹配,结果超时了,很是不解,反复改,优化,还是超时,最后没办法用了网上说的那个暴力,第一次还是超时了,看讨论,发现枚举的时候是i和j调换一下,按照算法的思路看时间复杂度没变,但是竟然ac了,MD,说实话,枚举的时间复杂度最坏是O(1000*1000*50*100),而KMP的时间复杂度是O(1000*(1000+50)*100)其实把i,j调换后AC了已经想到这个题目的数据的问题,我是在想不明白在概率的角度去考虑为什么横着枚举会比竖着枚举快(目前感觉就是后台数据的问题),但是如果是用KMP去跑的话把状态压缩改成竖着压缩应该能过,而且有可能会更快,这蛋疼数据。下面是暴力AC的代码和横着的KMP代码,暴力的好像是1500多AC的,横着的KMP超时了,有兴趣可以改成竖着试试,但是我不想改了,有点恶心了,那个KMP我优化了n多次,也重敲了n多次,对于这样的数据A不A已经不再重要。

状态压缩+暴力
#include<stdio.h>long long hash1[1005][1005];
long long hash2[55];bool jude(int n ,int m ,int p ,int q)
{int i ,j ,k;for(i = 1 ;i <= n - p + 1 ;i ++)for(j = 1 ;j <= m - q + 1 ;j ++){for(k = 1 ;k <= p ;k ++)if(hash1[i+k-1][j] != hash2[k])break;if(k == p + 1) return 1;}return 0;
}int main ()
{int n ,m ,t ,p ,q ,cas = 1 ,i ,j;char str[1005];long long T ,O ,I = 1;while(~scanf("%d %d %d %d %d" ,&n ,&m ,&t ,&p ,&q) && n + m + t + p + q){for(i = 1 ;i <= n ;i ++){scanf("%s" ,str);T = 0;for(j = 1 ;j <= m ;j ++){O = str[j-1] == '*';T = T * 2 + O;if(j >= q){hash1[i][j-q+1] = T;if(str[j-q]=='*') T = T - (I<<(q-1));}}}int ans = 0;while(t--){for(i = 1 ;i <= p ;i ++){scanf("%s" ,str);T = 0;for(j = 1 ;j <= q ;j ++){O = str[j-1] == '*';T = T * 2 + O;}hash2[i] = T;}if(p <= n && q <= m && jude(n ,m ,p ,q))ans ++;}printf("Case %d: %d\n" ,cas ++ ,ans);}return 0;
}状态压缩+KMP
#include<stdio.h>
#include<string.h>#define N 1000 + 10
#define M 50 + 5long long hash1[N][N];
long long hash2[M];
int next[M];
int map[N][N];void Get_Next(int m)
{int j = 0 ,k = -1;next[0] = -1;while(j < m){if(k == -1 || hash2[j] == hash2[k])next[++j] = ++k;else k = next[k];}return ;
}int KMP(int n ,int m ,int J)
{int i ,j;for(i = j = 0 ;i < n ;){if(hash1[i][J] == hash2[j]){if(j == m - 1) return 1;i ++ ,j ++;}else{j = next[j];if(j == -1)j = 0 ,i ++;}}return 0;
}int main ()
{int n ,m ,t ,p ,q ,i ,j ,cas = 1;char str[N];while(~scanf("%d %d %d %d %d" ,&n ,&m ,&t ,&p ,&q) && n + m + t + p + q){for(i = 1 ;i <= n ;i ++){scanf("%s" ,str);for(j = 0 ;j < m ;j ++)map[i][j+1] = str[j] == '*';}long long T ,O = 1;if(p <= n && q <= m)for(i = 1 ;i <= n ;i ++){T = 0;for(j = 1 ;j <= m ;j ++){T = T * (long long)2 + (long long)map[i][j];if(j >= q){hash1[i-1][j-q] = T;if(map[i][j-q+1]) T -= (O << (q - 1));}}}for(i = 0 ;i <= m ;i ++)hash1[n][i] = -1;int ans = 0;while(t--){for(i = 1 ;i <= p ;i ++){scanf("%s" ,str);T = 0;for(j = 0 ;j < q ;j ++){if(str[j] == '*') O = 1;else O = 0;T = T * 2 + O;}hash2[i-1] = T;}hash2[p] = -1;if(p > n || q > m) continue;Get_Next(p);for(i = 0 ;i <= m - q ;i ++){if(KMP(n ,p ,i)){ans ++;break;}}}printf("Case %d: %d\n" ,cas ++ ,ans);}return 0;
}

3690状态压缩+暴力相关推荐

  1. 状态压缩 + 暴力 HDOJ 4770 Lights Against Dudely

    题目传送门 题意:有n*m的房间,'.'表示可以被点亮,'#'表示不能被点亮,每点亮一个房间会使旁边的房间也点亮,有意盏特别的灯可以选择周围不同方向的房间点亮.问最少需要多少灯使得所有房间点亮 分析: ...

  2. Word UVA - 517 状态压缩 暴力搜索

    问题 https://vjudge.net/problem/UVA-517 分析 每次都循环到字典序最小的时候记录. 一共最多有2162^16216种,因为每种状态都变到字典序最小的时候,所以实际的远 ...

  3. HDU 1557 权利指数 国家压缩 暴力

    HDU 1557 权利指数 状态压缩 暴力 ACM 题目地址:HDU 1557 权利指数 题意:  中文题,不解释. 分析:  枚举全部集合,计算集合中的和,推断集合里面的团体是否为关键团队. 代码: ...

  4. POJ2688状态压缩(可以+DFS剪枝)

    题意:       给你一个n*m的格子,然后给你一个起点,让你遍历所有的垃圾,就是终点不唯一,问你最小路径是多少? 思路:       水题,方法比较多,最省事的就是直接就一个BFS状态压缩暴搜就行 ...

  5. POJ - 3279 Fliptile(状态压缩+位运算+暴力)

    题目链接:点击查看 题目大意:给出一个n*m的01矩阵,为了好描述,我们设0和1是两个相反的状态,我们的目标是要将整个矩阵全部变成1,现在我们可以将某一个点(x,y)更改为相反的状态,不过相应的该点周 ...

  6. 计蒜客 A2236 马的管辖 暴力枚举 状态压缩

    题目描述 原题链接 分析 结果填空题, 不用考虑时间复杂度,直接暴力枚举每一种方案 5×55×55×5的棋盘, 每一个格子有放或不放马两种状态, 所以一共需要枚举2252^{25}225种方案 每一种 ...

  7. 树上启动式合并问题 ---- D. Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths [状态压缩+树上启发式合并]

    题目链接 题目大意: 一棵根为1 的树,每条边上有一个字符(a−va−va−v共22种). 一条简单路径被称为Dokhtar−kosh当且仅当路径上的字符经过重新排序后可以变成一个回文串. 求每个子树 ...

  8. 点分治问题 ----------- HDU 5977 or 2016年大连ICPC [点分治+状态压缩]

    题目链接 题目大意: 就是给你一颗树,树上有各种权值,权值只有K种k∈[1,10]K种k\in[1,10]K种k∈[1,10],问你有多少路径覆盖了这KKK种权值,n∈[1,5e4]n\in[1,5e ...

  9. 解题报告(一)D、(CROC 2016 - Final Round C)Binary Table(矩阵 + 状态压缩 + FWT)(3.5)

    繁凡出品的全新系列:解题报告系列 -- 超高质量算法题单,配套我写的超高质量题解和代码,题目难度不一定按照题号排序,我会在每道题后面加上题目难度指数(1∼51 \sim 51∼5),以模板题难度 11 ...

最新文章

  1. 在线作图丨如何绘制精美的3D饼图
  2. 让汽车软件进入 iPhone 时代!
  3. ThreadPoolExecutor使用错误导致死锁
  4. JVM调优总结(2):一些概念(下)
  5. post from open live writer
  6. 如何设计LRU Cache算法
  7. 安装qgis显示python错误_ArcGIS 与 QGIS 3 冲突的解决方案
  8. linux 创建组,创建用户
  9. AngularJS快速入门指南09:SQL
  10. java socket 判断断网_java socket 判断对方在线或离线、断线
  11. 使用Tomcat+MyEclipse开发Java Web配置
  12. C# WinForm中获取当前程序运行目录的方法
  13. Resx 文件无效。未能加载 .RESX 文件中使用的类型 System.Collections.Generic.List`1请确保已在项目中添加了必需的引用。
  14. Ubuntu安装ffmpeg教程
  15. ajax hapi上传文件,在hapi框架里使用ajax提交表单数据,但是服务端接收到的数据是空对象。怎么办啊?...
  16. 使用CSS样式设置文本超出2行显示为省略号
  17. 技术资料收藏--有待整理
  18. 【Excel】工作表的并排比较
  19. 一阶的RC高低通电路和微积分电路有什么区别
  20. 深度科普:拆解让机器人走路更「丝滑」的TEB算法

热门文章

  1. NIST发布网络安全劳动力框架
  2. 【精致Java教程】02:Java的跨平台原理
  3. Revit二次开发之“使用ElementTransformUtils.MoveElement()移动元素”
  4. 分布式程序的自动化回归测试
  5. legend3---6、legend3爬坑杂记
  6. mysql 自定义提示符
  7. Javaweb 第1天 HTML和CSS课程
  8. [RouterOS] ROS对接碧海威或PA等流控实现完美流控详细教程(附脚本全免费)
  9. react问答 项目开发
  10. C#读取Excel显示到repeater中