【DP】2014年东莞市小学生程序设计复赛试题 打砖块

2014年东莞市小学生程序设计复赛试题 打砖块

题目

KXT是一个很无聊的小朋友,一天到晚都在打坐…
 一天,被他发现了一个比打坐更无聊的事情——打砖块。很多块砖分布在一个mm的矩阵中,他可以消掉以他为左上角顶点的一个nn的矩阵里的所有砖块。
 喜欢偷懒的他请来了你帮他计算可以消掉最多的砖块数(只能消一次)。

输入

第一行:用空格隔开的三个整数n、m、k。
接下来k行,每行2个用空格隔开的整数Xi、Yi,表示第i块砖在Xi行、Yi列的位置。

输入样例

5 10 11
2 1
4 6
4 9
3 9
9 7
9 9
7 9
8 10
8 8
8 6
10 2

输出

为可以消掉最多的砖块数。

输出样例

6

样例解释

在这里插入图片描述
站在第4行、6列的位置,可以消除6个方块。
   【数据范围】
  n<=m; k<=m*m
  60%:n<=70; m<=70; k<=4900
  100%:n<=1000; m<=1000; k<=1000000;

思路

这道题和最大子矩阵很像,只是它有固定的子矩阵边长,只要把最大子矩阵的循环和计算改一下,就OK了。

代码

#include<cstdio>
using namespace std;
int n,m,k,x,y,len[1001][1001],ans;//初始化
int main()
{
	scanf("%d%d%d",&n,&m,&k);//读入
	for(int i=1;i<=k;i++)
	{
		scanf("%d%d",&x,&y);//读入
		len[x][y]=1;//将坐标记为有砖
	}
	for(int i=1;i<=m;i++)
	 for(int j=1;j<=m;j++)
	  len[i][j]+=len[i-1][j];//求前缀和
	for(int i=1;i<=m-n+1;i++)
	 for(int j=1;j<=m-n+1;j++)
	 {
	 	int sum=0;//初始化
	 	for(int k=j;k<=j+n-1;k++)
	     sum=sum+len[i+n-1][k]-len[i-1][k];//求矩阵的和
	 	if(sum>ans) ans=sum;//求最大的
	 }
	printf("%d",ans);//输出
	return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_43346722/article/details/82957551