【杭电2015年12月校赛F】【二维DP】01 Matrix 大正方形内size为k的全1子正方形的个数
来源:互联网 发布:sql server进阶 编辑:程序博客网 时间:2024/06/05 10:02
01 Matrix
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 636 Accepted Submission(s): 139
Problem Description
It's really a simple problem.
Given a "01" matrix with size by n*n (the matrix size is n*n and only contain "0" or "1" in each grid), please count the number of "1" matrix with size by k*k (the matrix size is k*k and only contain "1" in each grid).
Given a "01" matrix with size by n*n (the matrix size is n*n and only contain "0" or "1" in each grid), please count the number of "1" matrix with size by k*k (the matrix size is k*k and only contain "1" in each grid).
Input
There is an integer T (0 < T <=50) in the first line, indicating the case number.
Each test case begins with two numbers n and m (0<n, m<=1000), specifying the size of matrix and the query number.
Then n lines follow and each line contains n chars ("0" or "1").
Then m lines follow, each lines contains a number k (0<k<=n).
Each test case begins with two numbers n and m (0<n, m<=1000), specifying the size of matrix and the query number.
Then n lines follow and each line contains n chars ("0" or "1").
Then m lines follow, each lines contains a number k (0<k<=n).
Output
For each query, output the number of "1" matrix with size by k*k.
Sample Input
22 20100123 3010111111122
Sample Output
10722
【杭电2015年12月校赛F】【二维DP O(n^2)做法】01 Matrix 大正方形内size为k的全1子正方形的个数
#include<stdio.h>#include<iostream>#include<string.h>#include<string>#include<ctype.h>#include<math.h>#include<set>#include<map>#include<vector>#include<queue>#include<bitset>#include<algorithm>#include<time.h>using namespace std;void fre(){freopen("c://test//input.in","r",stdin);freopen("c://test//output.out","w",stdout);}#define MS(x,y) memset(x,y,sizeof(x))#define MC(x,y) memcpy(x,y,sizeof(x))#define MP(x,y) make_pair(x,y)#define ls o<<1#define rs o<<1|1typedef long long LL;typedef unsigned long long UL;typedef unsigned int UI;template <class T1,class T2>inline void gmax(T1 &a,T2 b){if(b>a)a=b;}template <class T1,class T2>inline void gmin(T1 &a,T2 b){if(b<a)a=b;}const int N=1010,M=0,Z=1e9+7,ms63=0x3f3f3f3f;int casenum,casei;int n,m;char s[N][N];int d[N][N];int f[N];int main(){ scanf("%d",&casenum); for(casei=1;casei<=casenum;++casei) {MS(f,0); scanf("%d%d",&n,&m); for(int i=1;i<=n;++i)scanf("%s",s[i]+1); for(int i=1;i<=n;++i) { for(int j=1;j<=n;++j) {if(s[i][j]=='0')d[i][j]=0;else{int k=d[i-1][j-1];gmin(k,d[i-1][j]);gmin(k,d[i][j-1]);d[i][j]=k+1;++f[k+1];} } } for(int i=n;i>=2;--i)f[i-1]+=f[i]; while(m--) { int k; scanf("%d",&k); printf("%d\n",f[k]); } } return 0;}/*【题意】T(50)组数据每组数据给你一个n*n(1<=n<=1000)的01矩阵同时有m(1<=m<=1000)个询问对于每个询问,有尺寸k,让你求出,这个大的01矩阵中,有多少个size为k*k的小矩阵,满足小矩阵的每个数字都为1。【类型】DP【分析】询问辣么多!于是显然,我们直接预处理出每个size的矩形的个数就好啦。然后怎么做呢?提供两种做法:做法1,首先你要会一个最基本的,利用二维前缀和 求二维子矩阵数值和的做法利用这个做法,可以查询一个子矩阵是否为全1矩阵。然后,我们枚举子矩阵的右下角位置,然后二分得到——"以这个位置为右下角的,最大的全1正方形的size是多少"如果size为l,意味着size={1~l}的全1正方形的计数会各多1个。我们可以只计数++f[l];然后我们把f[]从大到小扫描一遍,f[i-1]+=f[i]。最后的f[k]就是大小为k的全1正方形的个数啦。时间复杂度O(n^2 logn)做法2,我们用d[i][j]表示右下角为(i,j)的最大的全1正方形的size是多少。那么直接有一个DP转移if(s[i][j]=='1')d[i][j]=max(d[i-1][j],max(d[i][j-1],d[i-1][j-1]))+1;else d[i][j]=0;然后一样计数++f[d[i][j]]最后扫描一遍就可以啦。时间复杂度O(n^2)*/
【杭电2015年12月校赛F】【二维DP 二分O(n^2logn)做法】01 Matrix 大正方形内size为k的全1子正方形的个数
#include<stdio.h>#include<algorithm>#include<ctype.h>#include<string.h>using namespace std;int casenum,casei;typedef long long LL;const int N=1005;int n,m;char s[N][N];int a[N][N];int line[N];int f[N];int main(){ scanf("%d",&casenum); for(casei=1;casei<=casenum;++casei) { scanf("%d%d",&n,&m); for(int i=1;i<=n;++i)scanf("%s",s[i]+1); memset(line,0,sizeof(line)); memset(f,0,sizeof(f)); for(int i=1;i<=n;++i) { for(int j=1;j<=n;++j) { line[i]+=(s[i][j]=='1'); a[i][j]=a[i-1][j]+line[i]; if(s[i][j]=='1') { int l=1; int r=min(i,j); while(l<r) { int mid=(l+r+1)>>1; int sum=a[i][j]-a[i-mid][j]-a[i][j-mid]+a[i-mid][j-mid]; if(sum==mid*mid)l=mid; else r=mid-1; } ++f[l]; } } } for(int i=n;i>=2;--i)f[i-1]+=f[i]; while(m--) { int k; scanf("%d",&k); printf("%d\n",f[k]); } } return 0;}/*【题意】T(50)组数据每组数据给你一个n*n(1<=n<=1000)的01矩阵同时有m(1<=m<=1000)个询问对于每个询问,有尺寸k,让你求出,这个大的01矩阵中,有多少个size为k*k的小矩阵,满足小矩阵的每个数字都为1。【类型】DP【分析】询问辣么多!于是显然,我们直接预处理出每个size的矩形的个数就好啦。然后怎么做呢?提供两种做法:做法1,首先你要会一个最基本的,利用二维前缀和 求二维子矩阵数值和的做法利用这个做法,可以查询一个子矩阵是否为全1矩阵。然后,我们枚举子矩阵的右下角位置,然后二分得到——"以这个位置为右下角的,最大的全1正方形的size是多少"如果size为l,意味着size={1~l}的全1正方形的计数会各多1个。我们可以只计数++f[l];然后我们把f[]从大到小扫描一遍,f[i-1]+=f[i]。最后的f[k]就是大小为k的全1正方形的个数啦。时间复杂度O(n^2 logn)做法2,我们用d[i][j]表示右下角为(i,j)的最大的全1正方形的size是多少。那么直接有一个DP转移if(s[i][j]=='1')d[i][j]=min(d[i-1][j],min(d[i][j-1],d[i-1][j-1]))+1;else d[i][j]=0;然后一样计数++f[d[i][j]]最后扫描一遍就可以啦。时间复杂度O(n^2)*/
0 0
- 【杭电2015年12月校赛F】【二维DP】01 Matrix 大正方形内size为k的全1子正方形的个数
- 01 Matrix 杭电2015年12月校赛F (二维DP)
- 01二维矩阵中最大全为1的正方形maxSquare
- dp 最大全1子正方形
- 计算正方形的个数
- 正方形内的计数
- 正方形个数(二维点哈希)
- POJ2002 正方形的个数(二维点的哈希)
- JZOJ1332. 正方形内的计数
- 固定为正方形的容器
- 趣题:单位正方形内相互分离的两个小正方形,其边长和小于1
- 求邊數為N的正方形所含的小正方形數目,并打印出子正方形
- hdu 2589 正方形划分 大正方形中又多个点 之后分成多个正方形 使得所有的正方形中含有1个点
- POJ2002---Squares(找正方形的个数)
- hdu4846 最大子正方形(dp)
- 正方形个数
- 大视野1047 [HAOI2007]理想的正方形
- 设置GridView的item为正方形
- 一些可以查询IP地理位置、身份证所在地、手机归属地的接口
- 10 条提升 Android 性能的建议
- arduino中断和一些问题
- 25个Java机器学习工具和库
- 一个典型PHP支付系统的设计与实现
- 【杭电2015年12月校赛F】【二维DP】01 Matrix 大正方形内size为k的全1子正方形的个数
- (二)代理模式C++
- 关于LINUX在中断(硬软)中不能睡眠的原因
- iOS自动布局第三方库Masonry的使用
- WEB 开发者应该具备的 6 大技能?
- java.lang.IllegalStateException: Already using output stream分析及处理办法
- php declare 的应用场景?
- iOS消息推送机制的实现
- 2015-12-28