Codeforces 611C New Year and Domino DP+前缀和
2016-12-29 22:32
477 查看
点击打开链接
题意:
给你个矩阵,每个位置是空或者不空
每两个相邻空的位置,可以放一个木条
有q次询问,每次问你一个子矩阵中,放一根木条有多少种放法
//q<=1e5 1<=w,h<=500 3秒时限
O(2wh+q(w+h)) 约为1e7
定义好状态即可:/f[i][j] 第i行横着放,前j列&&以第j列为终点(第2个'.'在第j列上)连续2个.的个数
//cos A=(b2+c2-a2)/2bc
#include <bits/stdc++.h>
typedef long long ll;
using namespace std;
const int N=6e2+20;
char g
;
int h,w;
int f
,d
;//f[i][j] 第i行横着放,前j列&&以第j列为终点(第2个'.'在第j列上)连续2个.的个数
void init()
{
memset(f,0,sizeof(f));
memset(d,0,sizeof(d));
for(int i=1;i<=h;i++)
{
f[i][0]=0;
f[i][1]=0;
for(int j=2;j<=w;j++)
{
if(g[i][j]=='.'&&g[i][j-1]=='.')
f[i][j]=f[i][j-1]+1;
else
f[i][j]=f[i][j-1];
//cout<<f[i][j]<<' ';
}
//cout<<endl;
}
for(int j=1;j<=w;j++)
{
d[0][j]=0;
d[1][j]=0;
for(int i=2;i<=h;i++)
{
if(g[i][j]=='.'&&g[i-1][j]=='.')
d[i][j]=d[i-1][j]+1;
else
d[i][j]=d[i-1][j];
}
}
}
int main()
{
while(scanf("%d%d",&h,&w)!=EOF)
{
for(int i=1;i<=h;i++)
scanf("%s",g[i]+1);
init();
int q;
scanf("%d",&q);
//q<=1e5 1<=w,h<=500 3秒时限
//O(2wh+q(w+h)) 1e7
while(q--)
{
int r1,c1,r2,c2;
scanf("%d%d%d%d",&r1,&c1,&r2,&c2);
int ans=0;
for(int i=r1;i<=r2;i++)
ans+=f[i][c2]-f[i][c1];
for(int j=c1;j<=c2;j++)
ans+=d[r2][j]-d[r1][j];
cout<<ans<<endl;
}
}
return 0;
}
题意:
给你个矩阵,每个位置是空或者不空
每两个相邻空的位置,可以放一个木条
有q次询问,每次问你一个子矩阵中,放一根木条有多少种放法
//q<=1e5 1<=w,h<=500 3秒时限
O(2wh+q(w+h)) 约为1e7
定义好状态即可:/f[i][j] 第i行横着放,前j列&&以第j列为终点(第2个'.'在第j列上)连续2个.的个数
//cos A=(b2+c2-a2)/2bc
#include <bits/stdc++.h>
typedef long long ll;
using namespace std;
const int N=6e2+20;
char g
;
int h,w;
int f
,d
;//f[i][j] 第i行横着放,前j列&&以第j列为终点(第2个'.'在第j列上)连续2个.的个数
void init()
{
memset(f,0,sizeof(f));
memset(d,0,sizeof(d));
for(int i=1;i<=h;i++)
{
f[i][0]=0;
f[i][1]=0;
for(int j=2;j<=w;j++)
{
if(g[i][j]=='.'&&g[i][j-1]=='.')
f[i][j]=f[i][j-1]+1;
else
f[i][j]=f[i][j-1];
//cout<<f[i][j]<<' ';
}
//cout<<endl;
}
for(int j=1;j<=w;j++)
{
d[0][j]=0;
d[1][j]=0;
for(int i=2;i<=h;i++)
{
if(g[i][j]=='.'&&g[i-1][j]=='.')
d[i][j]=d[i-1][j]+1;
else
d[i][j]=d[i-1][j];
}
}
}
int main()
{
while(scanf("%d%d",&h,&w)!=EOF)
{
for(int i=1;i<=h;i++)
scanf("%s",g[i]+1);
init();
int q;
scanf("%d",&q);
//q<=1e5 1<=w,h<=500 3秒时限
//O(2wh+q(w+h)) 1e7
while(q--)
{
int r1,c1,r2,c2;
scanf("%d%d%d%d",&r1,&c1,&r2,&c2);
int ans=0;
for(int i=r1;i<=r2;i++)
ans+=f[i][c2]-f[i][c1];
for(int j=c1;j<=c2;j++)
ans+=d[r2][j]-d[r1][j];
cout<<ans<<endl;
}
}
return 0;
}
相关文章推荐
- Web基础知识三之文本标记
- MAC 忘记mysql root 密码的解决办法
- 事务
- BZOJ3209 花神的数论题
- 抽象类和接口的区别
- Druid连接池
- 抽象类概念用法及注意事项
- CSE351 Lab1:使用C语言进行位操作
- Linux shell的&&和||
- 指令周期、机器周期、时钟周期
- c++时间转换与表示之02(计时)
- Spring-AOP详解
- 【工具类】Arrays工具类的简单使用
- 测试小故事11:登录与登陆
- MyBatis 判断条件为等于的问题
- 微服务限流设计
- Qt Disable QDebug And Warning Output
- eclipse快捷键大全
- miguaday 06 解决listview与SwipeRefreshLayout滑动冲突问题
- SIFT算法详解