前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【CodeForces 611C】New Year and Domino

【CodeForces 611C】New Year and Domino

作者头像
饶文津
发布2020-06-02 14:37:59
3990
发布2020-06-02 14:37:59
举报
文章被收录于专栏:饶文津的专栏饶文津的专栏

题意

  h行w列的矩形格子,“." 代表空的,"#" 代表满的,多米诺是 1*2 的长方体,现在放进格子,给你子矩形的左上角和右上角,问在子矩形里共有多少种放一块多米诺的方法。

分析

  如果是空的,我们存为a[i][j]=1;满的为0。

  我们可以储存 b[i][j] 表示前 i 行 j 列有多少种放法,递推来求。

  要求的大矩形的放法总数,就是粉色+紫色+蓝色+白色和红色框框的放法。

b[i][j-1]就是粉色+紫色,b[i-1][j]就是粉色+蓝色

b[i][j] += b[i][j-1] + b[i-1][j] -b[i-1][j-1]。

如果a[i][j]==1,b[i][j] += a[i][j-1]+a[i-1][j]。

  针对每个询问:r1,c1到r2,c2 共有多少放法

ans += b[r2][c2] - b[r2][c1-1] - b[r1-1][c2] + b[r1-1][c1-1]。

接下来判断边界是否还有如图中白色框框的,要减去。

r1到r2行,如果c1列为空,而c1-1列也为空,那就要减去,

c1到c2列,如果r1行为空,而r1-1行也为空,那也要减去。

代码

代码语言:javascript
复制
#include <stdio.h>
#include <algorithm>
#define F(a,b,c) for(int a=b;a<=c;a++)
#define N 505
using namespace std;
int h,w,a[N][N],b[N][N],q,ans;
int r1,c1,r2,c2;
char ch;
int main()
{
    scanf("%d%d",&h,&w);
    F(i,1,h)F(j,1,w)
    {
        scanf(" %c",&ch);
        if (ch == '.')
            a[i][j]=1;
    }
    F(i,1,h)F(j,1,w)
    {
        b[i][j] = b[i][j-1] + b[i-1][j] - b[i-1][j-1];
        if (a[i][j])
            b[i][j] += a[i][j-1] + a[i-1][j];
    }
    scanf("%d",&q);
    F(i,1,q)
    {
        scanf("%d%d%d%d",&r1,&c1,&r2,&c2);
        ans = b[r2][c2] - b[r2][c1-1] - b[r1-1][c2] + b[r1-1][c1-1];
        F(j,r1,r2)
        if (a[j][c1] && a[j][c1-1])
            ans--;

        F(j,c1,c2)
        if (a[r1][j] && a[r1-1][j])
            ans--;

        printf("%d\n",ans);
    }
    return 0;
}
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2016-02-17 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 分析
  • 代码
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档