农田个数

农田个数

题目描述
你的老家在农村。过年时,你回老家去拜年。你家有一片N×MN×M农田,将其看成一个N×MN×M的方格矩阵,有些方格是一片水域。你的农村伯伯听说你是学计算机的,给你出了一道题: 他问你:这片农田总共包含了多少个不存在水域的正方形农田。

两个正方形农田不同必须至少包含下面的两个条件中的一条:

1.边长不相等

2.左上角的方格不是同一方格

输入格式

输入数据第一行为两个由空格分开的正整数N、M(1<=m< n <=1000)

第2行到第N+1行每行有M个数字(0或1),描述了这一片农田。0表示这个方格为水域,否则为农田(注意:数字之间没有空格,而且每行不会出现空格)

输出格式

满足条件的正方形农田个数。

样例数据
input

3 3
110
110
000

output

5

样例解释

边长为1的正方形农田有4块 边长为2的正方形农田有1块,合起来就是5块

`数据规模与约定
时间限制:1s1s
空间限制:256MB256MB


。其实我现在主要是来倾诉写完这道题的心酸的。

今天下午老师是讲过这道题的,当时听起来的时候感觉蛮简单。代码也不长,最后AC的代码才37行。(还有三行废话)

。可是我写了好久。

首先样例太水了。

农田个数_第1张图片

样例的图很容易画(毕竟只有 3*3 )。蓝色代表水塘,黄色代表农田。而那些绿的只是代表坐标用的。

方格里的数代表以这个位置为右下角的正方形数有多少。等推完了以后再将整个 f[i][j] 数组加起来。

然后看样例的(2,2)中 f[2][2] 的值来自 f[1][1]+1
但之所以会+1是因为 a[1][2] (a数组存储是水塘还是农田)为 1 ( 农田) 且 a[2][1] 也是 1 (农田)。

所以搜索顺序是一行行,我就先判断a[2-1][2]a[2][2-1] 是否满足条件,若满足,f[2][2] 中的值就是 f[2-1][2-1]+1

若是之前那个数为2,那就不只要判断 f[i-1][j] f[i][j-1] 的条件了,还要判断 f[i-2][j] f[i][j-2] 所以到底要判断到哪里还是要计算一下的。 我是这样算的:

		if(a[i][j]=='1') f[i][j]=1;//自己不是水塘,但左上角是水塘 
		if(a[i][j]=='1'&&a[i-1][j-1]!=0)//自己不是水塘,且左上角有农田 
		{
			int check=1;//检验是否都是农田 
			for(int k=1;k<=f[i-1][j-1];k++)
			{
				if(a[i-k][j]=='0') check=0;
				if(a[i][j-k]=='0') check=0;
			}
			if(check==1) f[i][j]=f[i-1][j-1]+1;		
		}

然后写完程序我去提交了,只得了20!

哎呀我的妈,数据很大,最小的也只有50*50

这。。我本来还想把数据拿来打个表的,这也太大了,要我怎么画图啊。

我只能去拷贝了一下别人的程序,进行打表找不同。经过千辛万苦,跨过山和大海啊,我终于找到了不同。

用的数据是这么一组

9 8
00111001
10010111
01010101
00111111
00111111
00111111
01011011
01000001
01001110

正确的表:

0 0 1 1 1 0 0 1
1 0 0 1 0 1 1 1
0 1 0 1 0 1 0 1
0 0 1 1 1 1 1 1
0 0 1 2 2 2 2 2
0 0 1 2 3 3 3 3
0 1 0 1 2 0 1 2
0 1 0 0 0 0 0 1
0 1 0 0 1 1 1 0

然后我打出来的表:

0 0 1 1 1 0 0 1
1 0 0 1 0 1 1 1
0 1 0 1 0 1 0 1
0 0 1 1 1 1 1 1
0 0 1 2 2 2 2 2
0 0 1 2 3 3 3 3
0 1 0 1 1 0 1 1
0 1 0 0 0 0 0 1
0 1 0 0 1 1 1 0

然后我又绘了一张图:

农田个数_第2张图片
然后我找到了原因。列如位置**(8,7)**,按照我原先的思路,那里应该是 1 而现实是 2

因为虽然 f[8-3][8]!=0 ,还是有两个正方形的。我修改了1个半小时的程序,才改好。

不要问我为什么改这么久。我。。。渣。。一直理不清思路,搞清思路后没多久就写完了代码。

好了,最后是AC的代码


/*天灵灵!地灵灵!让我过吧!我做了几个小时了!*/

#include
using namespace std;
char a[5000][5000]={};
int f[5000][5000]={};
int N,M; 
int tmp=0;
int main()
{
//	freopen("count.in","r",stdin);
//	freopen("count.out","w",stdout);
	cin>>N>>M;
	for(int i=1;i<=N;i++)
	for(int j=1;j<=M;j++)
	cin>>a[i][j];
	for(int i=1;i<=N;i++)
	for(int j=1;j<=M;j++)
	{
		if(a[i][j]=='0') f[i][j]=0;//自己本身就是水塘  
		if(a[i][j]=='1')//自己不是水塘
		{
			int tmp=0;
			for(int k=1;k<=f[i-1][j-1]+1;k++)
			{
				tmp++;
				if(a[i-k][j]=='0') break;
				if(a[i][j-k]=='0') break;
			}
			f[i][j]=tmp;
		}
		tmp=tmp+f[i][j];//相加 
	}
	for(int i=1;i<=N;i++)
	{
		for(int j=1;j<=M;j++)
		cout<

2019-03-19 21:12

你可能感兴趣的:(题目)