• [USACO3.3.4]range


      题目传送门:http://www.nocow.cn/index.php/Translate:USACO/range

      这道题的话如果不是之前做过类似的题目,我想我是做不出来的,大概就是先预处理s[i][j],表示前i行前j列有多少个1,然后O(1)时间判断这个正方形是否有1。

      s[i][j]显然等于是s[i-1][j]+s[i][j-1]-s[i-1][j-1]+f[i][j](两个多边形重复的部分为s[i-1][j-1])

      而判断第i行到第l行,第j列到第k列这个多边形内有没有(j-k+1)*(l-i+1)个1,显然只需判断s[i][j]-s[i-1][k]-s[l][j-1]+s[i-1][j-1]是否等于(j-k+1)*(l-i+1)就行了。(两个多边形的重复部分为s[i-1][j-1])

      会有一点乱,但只要想一想图就好了,而且这道题是正方形,只要枚举边的长度就好了.

      

    /*
    ID:abc31261
    LANG:C++
    TASK:range
    */
    
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    using namespace std;
    const int maxn=260;
    int n,f[maxn][maxn],s[maxn][maxn],num[maxn];
    int main()
    {
    	int i,j,l;
    	freopen("range.in","r",stdin);
    	freopen("range.out","w",stdout);
    	scanf("%d",&n);
    	for (i=1;i<=n;i++)
    		for (j=1;j<=n;j++)scanf("%01d",&f[i][j]);
    	memset(s,0,sizeof(s));
    	memset(num,0,sizeof(num));
    	for (i=1;i<=n;i++)
    		for (j=1;j<=n;j++)s[i][j]=s[i-1][j]+s[i][j-1]-s[i-1][j-1]+f[i][j];
    	for (i=1;i<=n;i++)
    		for (j=1;j<=n;j++)
    			for (l=2;l<=min(n-i+1,n-j+1);l++)
    			{
    				int x=i+l-1,y=j+l-1;
    				if (s[x][y]-s[x][j-1]-s[i-1][y]+s[i-1][j-1]==l*l)num[l]++;
    			}
    	for (i=1;i<=n;i++)
    		if (num[i]!=0)printf("%d %d
    ",i,num[i]);
    	return 0;
    }
    

      

  • 相关阅读:
    【笔记】二进制文件
    vs2015+64位win10系统ceres-solver编译
    python
    感受函数式编程-scala
    R语言diagram包画订单状态流图
    virtualbox下Centos6.5桥接模式上网配置方法
    配置对IIS上tabular的 HTTP 访问
    centos6.5下逻辑卷操作
    centos6.5下磁盘创建交换分区
    centos6.5下磁盘分区及挂载
  • 原文地址:https://www.cnblogs.com/Sun-Sea/p/5289946.html
Copyright © 2020-2023  润新知