hdu 01 Matrix
2015-12-27 17:52
218 查看
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 605 Accepted Submission(s): 127
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).
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).
Output
For each query, output the number of "1" matrix with size by k*k.
Sample Input
2
2 2
01
00
1
2
3 3
010
111
111
1
2
2
Sample Output
1
0
7
2
2
这题用二维树状数组T了,改成用dp做,371ms过了。我们枚举每一个点作为右下角的点对各部分的贡献,那么就可以dp了。
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<string>
#include<algorithm>
using namespace std;
typedef long long ll;
#define pi acos(-1.0)
#define maxn 1006
int n;
char s[maxn][maxn];
int b[maxn],dp[maxn][maxn],heng[maxn][maxn],shu[maxn][maxn];
int lowbit(int x){
return x&(-x);
}
void update(int pos,int num)
{
while(pos<=maxn){
b[pos]+=num;pos+=lowbit(pos);
}
}
int getsum(int pos)
{
int num=0;
while(pos>0){
num+=b[pos];pos-=lowbit(pos);
}
return num;
}
int main()
{
int m,i,j,T,d;
int l,r,mid;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++){
scanf("%s",s[i]+1);
}
for(i=1;i<=n;i++){
b[i]=0;
for(j=1;j<=n;j++){
shu[i][j]=0;
heng[i][j]=0;
}
}
/*
memset(b,0,sizeof(b));
memset(shu,0,sizeof(shu));
memset(heng,0,sizeof(heng));
memset(dp,0,sizeof(dp));
*/
for(i=1;i<=n;i++){
for(j=1;j<=n;j++){
if(i==1 && j==1){
if(s[i][j]=='1'){
dp[i][j]=shu[i][j]=heng[i][j]=1;
update(1,1);
update(2,-1);
}
else{
dp[i][j]=shu[i][j]=heng[i][j]=0;
}
continue;
}
if(s[i][j]=='0'){
dp[i][j]=shu[i][j]=heng[i][j]=0;
continue;
}
if(i==1){
dp[i][j]=1;
heng[i][j]=heng[i][j-1]+1;
shu[i][j]=1;
update(1,1);
update(dp[i][j]+1,-1);
}
else if(j==1){
dp[i][j]=1;
heng[i][j]=1;
shu[i][j]=shu[i-1][j]+1;
update(1,1);
update(dp[i][j]+1,-1);
}
else{
heng[i][j]=heng[i][j-1]+1;
shu[i][j]=shu[i-1][j]+1;
int len=min(heng[i][j],shu[i][j]);
len=min(len,dp[i-1][j-1]+1);
dp[i][j]=len;
update(1,1);
update(len+1,-1);
}
}
}
for(i=1;i<=m;i++){
scanf("%d",&d);
printf("%d\n",getsum(d));
}
}
return 0;
}
Total Submission(s): 605 Accepted Submission(s): 127
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).
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).
Output
For each query, output the number of "1" matrix with size by k*k.
Sample Input
2
2 2
01
00
1
2
3 3
010
111
111
1
2
2
Sample Output
1
0
7
2
2
这题用二维树状数组T了,改成用dp做,371ms过了。我们枚举每一个点作为右下角的点对各部分的贡献,那么就可以dp了。
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<string>
#include<algorithm>
using namespace std;
typedef long long ll;
#define pi acos(-1.0)
#define maxn 1006
int n;
char s[maxn][maxn];
int b[maxn],dp[maxn][maxn],heng[maxn][maxn],shu[maxn][maxn];
int lowbit(int x){
return x&(-x);
}
void update(int pos,int num)
{
while(pos<=maxn){
b[pos]+=num;pos+=lowbit(pos);
}
}
int getsum(int pos)
{
int num=0;
while(pos>0){
num+=b[pos];pos-=lowbit(pos);
}
return num;
}
int main()
{
int m,i,j,T,d;
int l,r,mid;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++){
scanf("%s",s[i]+1);
}
for(i=1;i<=n;i++){
b[i]=0;
for(j=1;j<=n;j++){
shu[i][j]=0;
heng[i][j]=0;
}
}
/*
memset(b,0,sizeof(b));
memset(shu,0,sizeof(shu));
memset(heng,0,sizeof(heng));
memset(dp,0,sizeof(dp));
*/
for(i=1;i<=n;i++){
for(j=1;j<=n;j++){
if(i==1 && j==1){
if(s[i][j]=='1'){
dp[i][j]=shu[i][j]=heng[i][j]=1;
update(1,1);
update(2,-1);
}
else{
dp[i][j]=shu[i][j]=heng[i][j]=0;
}
continue;
}
if(s[i][j]=='0'){
dp[i][j]=shu[i][j]=heng[i][j]=0;
continue;
}
if(i==1){
dp[i][j]=1;
heng[i][j]=heng[i][j-1]+1;
shu[i][j]=1;
update(1,1);
update(dp[i][j]+1,-1);
}
else if(j==1){
dp[i][j]=1;
heng[i][j]=1;
shu[i][j]=shu[i-1][j]+1;
update(1,1);
update(dp[i][j]+1,-1);
}
else{
heng[i][j]=heng[i][j-1]+1;
shu[i][j]=shu[i-1][j]+1;
int len=min(heng[i][j],shu[i][j]);
len=min(len,dp[i-1][j-1]+1);
dp[i][j]=len;
update(1,1);
update(len+1,-1);
}
}
}
for(i=1;i<=m;i++){
scanf("%d",&d);
printf("%d\n",getsum(d));
}
}
return 0;
}
相关文章推荐
- 分享一下PHP中的While循环函数,以前觉得挺难的
- Windows系统性能提升方法
- C#中Console.WriteLine()的用法
- 如何学习递归,回溯,DFS,BFS.
- ContentProvider
- linux(CentOS6.5)之postfix服务器编译安装
- 使用PHP循环函数的一些知识,那些不曾了解的知识
- 库函数 产生任意不重复随机数
- 逆波兰表达式-stack的运用
- 使用Android studio 提交代码无反应的处理办法
- U3D 精灵的点击监听
- 工厂模式个构造函数的区别
- μC/OS-Ⅱ下的九个C语言文件功能函数大全
- 域套接字代码示例(2)
- API判断本机安装的Revit版本信息
- 价值博客列表
- Hadoop2.6.0完全集群安装配置
- 浏览器内核
- [leetcode] 168. Excel Sheet Column Title 解题报告
- ios项目中引用其他项目复习