标签:const lib ems its amp ima question 整数 分析
如图所示,在由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@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
标签:const lib ems its amp ima question 整数 分析
原文地址:https://www.cnblogs.com/paulzjt/p/10182000.html