问题 D: 约会-UPC三十场(前缀和)

   日期:2020-05-31     浏览:112    评论:0    
核心提示:题目描述从前,小兔发现了一个神秘的花园。花园是一个 n 行 m 列的矩阵,第 i 行 j 列的花的美丽度为 ai,j,一个合法的约会场所为任意一个正方形子矩阵,定义子矩阵的浪漫度为这个子矩阵的两条对角线上的花的美丽度之和。现在小兔想选一个面积大等于 1 的约会场所使得场所的浪漫度最大,以便和小鹿约会,因为小兔忙着 AKIOI ,所以她把这个问题交给了你。输入第一行,两个正整数 n,m。接下来是一个 n 行 m 列的矩阵,表示各个位置上花的美丽度。输出仅一行,一个正整数,表示最大的浪漫度。样

题目描述
从前,小兔发现了一个神秘的花园。

花园是一个 n 行 m 列的矩阵,第 i 行 j 列的花的美丽度为 ai,j,一个合法的约会场所为任意一个正方形子矩阵,定义子矩阵的浪漫度为这个子矩阵的两条对角线上的花的美丽度之和。

现在小兔想选一个面积大等于 1 的约会场所使得场所的浪漫度最大,以便和小鹿约会,因为小兔忙着 AKIOI ,所以她把这个问题交给了你。
输入
第一行,两个正整数 n,m。
接下来是一个 n 行 m 列的矩阵,表示各个位置上花的美丽度。
输出
仅一行,一个正整数,表示最大的浪漫度。
样例输入 Copy
3 3
2 -1 3
-4 2 1
1 2 -1
样例输出 Copy
7
提示
对于 40%的数据,n,m≤10。
对于 100%的数据,1≤n,m≤300,∣ai∣≤104。

思路
如果直接暴力能过的话,你我此时此刻也不会在此见面
不过也跟暴力没什么区别,维护对角线的前缀和
用B数组维护主对角线的前缀和,用C数组维护副对角线的前缀和
然后枚举左上角的点和正方形的边长
然后O(1) 获得 浪漫度,
最后取max

代码

#include <map>
#include <set>
#include <cmath>
#include <stack>
#include <queue>
#include <cstdio>
#include <bitset>
#include <vector>
#include <iomanip>
#include <sstream>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <unordered_map>
#define UpMing main
#define re register
#pragma GCC optimize(2)
#define Accept return 0;
#define lowbit(x) ((x)&(-(x)))
#define mst(x, a) memset(x,a,sizeof(x))
#define rep(i,a,b) for(int i=(a);i<=(b);++i)
#define dep(i,a,b) for(int i=(a);i>=(b);--i)
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
typedef unsigned long long ull;
const int inf =0x3f3f3f3f;
const int maxn=2e6+7;
const ll mod = 998244353;
const int N =1e6+7;
inline ll read() {
	ll  x=0;
	bool f=0;
	char ch=getchar();
	while (ch<'0'||'9'<ch)    f|=ch=='-', ch=getchar();
	while ('0'<=ch && ch<='9')
		x=x*10+ch-'0',ch=getchar();
	return f?-x:x;
}
void out(ll x) {
	int stackk[20];
	if(x<0) {
		putchar('-');
		x=-x;
	}
	if(!x) {
		putchar('0');
		return;
	}
	int top=0;
	while(x) stackk[++top]=x%10,x/=10;
	while(top) putchar(stackk[top--]+'0');
}
ll a[1333][1333],n,m,ans,b[1311][1313],c[1311][1313];
ll f(ll x,ll y,ll z) {
	if(z%2)
		return (b[x+z][y+z]-b[x-1][y-1])+(c[x+z][y]-c[x-1][y+z+1]);
	else
		return (b[x+z][y+z]-b[x-1][y-1])+(c[x+z][y]-c[x-1][y+z+1])-a[x+z/2][y+z/2];
}
int UpMing() {
	cin>>n>>m;
	for(int i=1 ; i<=n ; i++)
		for(int j=1 ; j<=m ; j++) {
			cin>>a[i][j];
			ans=max(ans,a[i][j]);
		}
	for(int i=1 ; i<=n ; i++)
		for(int j=1 ; j<=m ; j++) {
			for(int x=i,y=j; x<=n&&y<=m ; y++,x++)
				b[x][y]=b[x-1][y-1]+a[x][y];
		}
		
	for(int i=1 ; i<=n ; i++)
		for(int j=1 ; j<=m ; j++) {
			for(int x=i,y=j; x<=n&&y>=1 ; y--,x++)
				c[x][y]=c[x-1][y+1]+a[x][y];
		}

	for(int len=1 ; len<min(n,m); len++)
		for(int i=1 ; i<=n-len ; i++)
			for(int j=1 ; j<=m-len; j++)
				ans=max(ans,f(i,j,len));
				
	out(ans);
	Accept;
}




 
打赏
 本文转载自:网络 
所有权利归属于原作者,如文章来源标示错误或侵犯了您的权利请联系微信13520258486
更多>最近资讯中心
更多>最新资讯中心
0相关评论

推荐图文
推荐资讯中心
点击排行
最新信息
新手指南
采购商服务
供应商服务
交易安全
关注我们
手机网站:
新浪微博:
微信关注:

13520258486

周一至周五 9:00-18:00
(其他时间联系在线客服)

24小时在线客服