zoukankan      html  css  js  c++  java
  • 统计01矩阵中全1子矩阵的个数

    统计01矩阵中全1子矩阵的个数

    1、51Nod 1291

    题意:600*600的01矩阵,统计宽i高j的全1矩阵的个数。

    题解:枚举矩阵的下边界,对于每个下边界,统计所有宽极大的矩形的答案(高度可以用差分)。(n^2) 统计完之后,我们已知所有高度的宽极大的答案,列一下式子发现两次前缀和就是最后答案。

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    #define fi first
    #define se second
    #define mp make_pair
    #define pb push_back
    #define rep(i, a, b) for(int i=(a); i<(b); i++)
    #define sz(x) (int)x.size()
    #define de(x) cout<< #x<<" = "<<x<<endl
    #define dd(x) cout<< #x<<" = "<<x<<" "
    typedef long long ll;
    typedef pair<int, int> pii;
    typedef vector<int> vi;
    
    const int N=666;
    int n,m,top;
    int u[N], sta[N];
    ll c[N][N];
    char s[N];
    
    int main() {
    	scanf("%d%d",&n,&m);
    	rep(i,1,n+1) {
    		scanf("%s",s+1);
    		rep(j,1,m+1) u[j]=(s[j]=='1')?u[j]+1:0;
    		top=0;
    		sta[++top]=0;
    		rep(j,1,m+2) {
    			while(u[sta[top]]>u[j]) {
    				++c[max(u[sta[top-1]], u[j])+1][j-sta[top-1]-1];
    				--c[u[sta[top]]+1][j-sta[top-1]-1];
    				--top;
    			}
    			while(top&&u[sta[top]]==u[j]) --top;
    			sta[++top]=j;
    		}
    	}
    	rep(i,2,n+1) rep(j,1,m+1) c[i][j]+=c[i-1][j];
    	rep(i,1,n+1) {
    		for(int j=m-1;j;--j) c[i][j]+=c[i][j+1];
    		for(int j=m-1;j;--j) c[i][j]+=c[i][j+1];
    	}
    	rep(i,1,n+1) rep(j,1,m+1) printf("%lld%c",c[i][j]," 
    "[j==m]);
    	return 0;
    }
    

    2、Wannafly挑战赛12 D

    题意:1e9*1e9的01矩阵,1的个数5000个,统计全0矩阵的个数。

    题解:所有情况 减去 包含1的。对于每个1,统计以它为最上左的答案。

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    #define fi first
    #define se second
    #define mp make_pair
    #define pb push_back
    #define rep(i, a, b) for(int i=(a); i<(b); i++)
    #define sz(x) (int)x.size()
    #define de(x) cout<< #x<<" = "<<x<<endl
    #define dd(x) cout<< #x<<" = "<<x<<" "
    typedef long long ll;
    typedef pair<int, int> pii;
    typedef vector<int> vi;
    
    const int N=5050, P=1e9+7;
    int n,m,c,ans;
    pii a[N];
    
    ll kpow(ll a, ll b) {
    	ll res=1;
    	while(b) {
    		if(b&1) res=res*a%P;
    		a=a*a%P;
    		b>>=1;
    	}
    	return res;
    }
    
    void upd(int &a, ll b) {
    	a+=b;
    	if(a>=P) a-=P;
    }
    
    int main() {
    	scanf("%d%d%d",&n,&m,&c);
    	rep(i,1,c+1) {
    		int x,y;scanf("%d%d",&x,&y);
    		a[i]=mp(x, y);
    	}
    	sort(a+1, a+1+c);
    	rep(i,1,c+1) {
    		int l=1, r=m;
    		for(int j=i-1;~j;--j) {
    			if(a[j].fi!=a[j+1].fi) upd(ans, 1ll*(n-a[i].fi+1)*(a[j+1].fi-a[j].fi)%P*(r-a[i].se+1)%P*(a[i].se-l+1)%P);
    			if(a[j].se<=a[i].se) l=max(l, a[j].se+1);
    			if(a[j].se>=a[i].se) r=min(r, a[j].se-1);
    		}
    	}
    	printf("%lld
    ",(1ll*n*(n+1)%P*m%P*(m+1)%P*kpow(4, P-2)%P-ans+P)%P);
    	return 0;
    }
    
  • 相关阅读:
    According to TLD or attribute directive in tag file, attribute end does not accept any expressions
    Several ports (8080, 8009) required by Tomcat v6.0 Server at localhost are already in use.
    sql注入漏洞
    Servlet—简单的管理系统
    ServletContext与网站计数器
    VS2010+ICE3.5运行官方demo报错----std::bad_alloc
    java 使用相对路径读取文件
    shell编程 if 注意事项
    Ubuntu12.04下eclipse提示框黑色背景色的修改方法
    解决Ubuntu环境变量错误导致无法正常登录
  • 原文地址:https://www.cnblogs.com/wuyuanyuan/p/8666316.html
Copyright © 2011-2022 走看看