zoukankan      html  css  js  c++  java
  • hiho一下第234周《矩形计数》题目与解答

    一、题目

    题目1 : 矩形计数

    时间限制:10000ms
    单点时限:1000ms
    内存限制:256MB

    描述

    如图所示,在由N行M列个单位正方形组成的矩形中,有K个单位正方形是黑色的,其余单位正方形是白色的。  

    你能统计出一共有多少个不同的子矩形是完全由白色单位正方形组成的吗?

    输入

    第一行三个整数:N, M和K。

    之后K行每行包括两个整数R和C,代表一个黑色单位正方形的位置。

    1 <= N,M <= 1000  

    1 <= K <= 10  

    1 <= R <= N  

    1 <= C <= M

    输出

    输出一个整数表示满足条件的子矩形个数。

    样例输入
    3 3 1
    2 3 
    样例输出
    24


    二、思路

    一开始没有思路,参考了官方分析之后豁然开朗。问题的关键点在于想到容斥原理和题解中的这句话:
    我们知道只要确定矩形上边界、下边界、左边界和右边界的位置,就唯一确定了一个矩形。

    三、实现

    dfs实现容斥原理可以考虑用二进制来表示选取的集合状态。

     1 //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@A@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
     2  #include <iostream>
     3  #include <cstring>
     4  #include <cstdio>
     5  #include <string>
     6  #include <queue>
     7  #include <list>
     8  #include <map>
     9  #include <set>
    10  #include <cmath>
    11  #include <bitset>
    12  #include <vector>
    13  #include <sstream>
    14  #include <cstdlib>
    15  #include <algorithm>
    16  using namespace std;
    17  typedef long long  ll;
    18  #define mem(A, X) memset(A, X, sizeof A)
    19  #define foreach(e,x) for(__typeof(x.begin()) e=x.begin();e!=x.end();++e)
    20  #define fori(i,l,u) for(ll (i)=(ll)(l);(i)<=(ll)(u);++(i))
    21  #define ford(i,l,u) for(ll (i)=(ll)(l);(i)>=(ll)(u);--(i)) 
    22 ll n,m,k;
    23 const int maxsz=1005;
    24 ll pr[maxsz],pc[maxsz];
    25 ll sum;
    26 ll cal(ll s){
    27   if (s==0) return (n*n+n)*(m*m+m)/4;
    28   ll lc=1000,rc=0,ur=0,dr=1000;
    29   int cnt=0;
    30 
    31   //cout<<"----- s is : "<<s;
    32   fori(i,1,k){
    33    if(s&1){
    34      lc=min(lc,pc[i]-1);
    35      rc=max(rc,pc[i]);
    36      ur=max(ur,pr[i]);
    37      dr=min(dr,pr[i]-1);
    38    }
    39    s=s>>1;
    40   }
    41   //cout<<"  lc rc ur dr"<<lc<<" "<<rc<<" "<<ur<<" "<<dr<<endl;
    42   ll sumx=(lc+1)*(m-rc+1);
    43   //if(lx==rx) sumx=n*lx-lx*rx+n-rx+lx;
    44   ll sumy=(dr+1)*(n-ur+1);
    45   //if(lx==rx) sumy=n*lx-lx*rx+n-rx+lx;
    46 
    47   return sumx*sumy;
    48 }
    49 void dfs(ll cnt,ll s){
    50   if(cnt<k){
    51     int ns=(s<<1)+0;
    52     dfs(cnt+1,ns);
    53     ns=(s<<1)+1;
    54     dfs(cnt+1,ns);
    55   }else{
    56     int cnt1=0;
    57     int ts=s;
    58     int cnt=k;
    59     while(cnt--) {
    60       if(ts&1) cnt1++;
    61       ts=ts>>1;
    62     }
    63     int sig=-1;
    64     if((cnt1%2)==0) sig=1;
    65     ll temp=cal(s);
    66     sum+=sig*temp;
    67   }
    68 
    69 }
    70 
    71 
    72  int main()
    73  {
    74   ios::sync_with_stdio(false);
    75   //freopen("local.in","r",stdin);
    76   //freopen("local.out","w",stdout);
    77 
    78   while(cin>>n>>m>>k){
    79     fori(i,1,k) cin>>pr[i]>>pc[i];
    80     sum=0;
    81     dfs(0,0);
    82     cout<<sum<<endl;
    83   }
    84 
    85   return 0;
    86  }
    87 
    88 //
    89 //
    90 //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@DEBUG@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
    View Code
  • 相关阅读:
    python(7)-pycharm mac和windows专业版安装破解
    Navicat Premium15激活 安装与激活(转载) 有效!!
    PHP 冒泡排序
    PHP 插入排序 -- 希尔排序
    PHP 插入排序 -- 折半查找
    PHP 插入排序 -- 直接插入排序
    PHP 哈夫曼的实现
    PHP call_user_func的一些用法和注意点
    PHP 组件注册的例子
    PHP 奇葩的debug_zval_dump的输出
  • 原文地址:https://www.cnblogs.com/paulzjt/p/10182000.html
Copyright © 2011-2022 走看看