bzoj1723 [ Usaco2009 Feb ] --前缀和(水题)

来源:互联网 发布:人民文学 知乎 编辑:程序博客网 时间:2024/05/17 20:29
题目大意:
你难以想象贝茜看到一只妖精在牧场出现时是多么的惊讶.她不是傻瓜,立即猛扑过去,用她那灵活的牛蹄抓住了那只妖精.
    “你可以许一个愿望,傻大个儿!”妖精说.
    “财富,”贝茜用梦游般的声音回答道,  “我要获得财富的机会.”
    妖精从来没有碰到过这么简单的愿望.他在地方划出一大块N×N(1≤N≤200)的方格,每个格子上写上_1,000,000到1,000,000之间的数字.他说:  “在方格上朝一个方向行走,可以是行的方向,列的方向,斜对角的方向,一步只能走一格,所有你踩过的数字的和就是你的财富.”
    贝茜请你来帮忙,找到一行、一列或一条对角线上找一段连续的数字,它们的和最大.由于妖精方格的神奇特性,沿着一个方向走,走到了边际,再一步跨过去可以“绕”到方格的对边出现.一行两端的格子是相邻的,一列两端的格子也是相邻的,甚至相邻两行的分别两端的格子也是相邻的(斜对角方向).
    对于下图左边的方格,所有标记过的数字都在一条对角线上.
  
 
对于这个方格,能踩出来的最大的和是24,踩过的数字在右图中标记出来了
 
思路:

我们可以维护行、列、对角线的前缀和,每次用当前和减去最小和、总和减去最小和更新答案。
由于行、列、对角线互不影响,O(n^2)枚举就可以了。
 
代码:
#include<cstdio>#include<iostream>#include<cstring>#include<algorithm>using namespace std;#define N 201inline char Nc(){    static char buf[100000],*p1=buf,*p2=buf;    if(p1==p2){        p2=(p1=buf)+fread(buf,1,100000,stdin);        if(p1==p2)return EOF;     }    return *p1++;}inline void Read(int& x){    char c=Nc(),b=1;    for(;c<'0'||c>'9';c=Nc())if(c=='-')b=-1;    for(x=0;c>='0'&&c<='9';x=(x<<3)+(x<<1)+c-48,c=Nc());x*=b;}int i,j,k,n,x[N][N],y[N][N],a[N][N],b[N][N],Ans=-1000000,Mix[N],Miy[N],Mia[N],Mib[N],Max[N],May[N],Maa[N],Mab[N];int main(){    Read(n);    for(i=1;i<=n;i++)    for(j=1;j<=n;j++){        Read(k);        x[i][j]=x[i][j-1]+k;        y[j][i]=y[j][i-1]+k;        a[(i-j+n)%n+1][i]=a[(i-j+n)%n+1][i-1]+k;        b[(i+j)%n+1][i]=b[(i+j)%n+1][i-1]+k;    }    for(i=1;i<=n;i++)    for(j=1;j<=n;j++){        if(x[i][j]-Mix[i]>Ans)Ans=x[i][j]-Mix[i];        if(y[i][j]-Miy[i]>Ans)Ans=y[i][j]-Miy[i];        if(a[i][j]-Mia[i]>Ans)Ans=a[i][j]-Mia[i];        if(b[i][j]-Mib[i]>Ans)Ans=b[i][j]-Mib[i];        if(x[i][n]-x[i][j-1]+Max[i]>Ans)Ans=x[i][n]-x[i][j-1]+Max[i];        if(y[i][n]-y[i][j-1]+May[i]>Ans)Ans=y[i][n]-y[i][j-1]+May[i];        if(a[i][n]-a[i][j-1]+Maa[i]>Ans)Ans=a[i][n]-a[i][j-1]+Maa[i];        if(b[i][n]-b[i][j-1]+Mab[i]>Ans)Ans=b[i][n]-b[i][j-1]+Mab[i];        if(x[i][j]<Mix[i])Mix[i]=x[i][j];        if(y[i][j]<Miy[i])Miy[i]=y[i][j];        if(a[i][j]<Mia[i])Mia[i]=a[i][j];        if(b[i][j]<Mib[i])Mib[i]=b[i][j];        if(x[i][j]>Max[i])Max[i]=x[i][j];        if(y[i][j]>May[i])May[i]=y[i][j];        if(a[i][j]>Maa[i])Maa[i]=a[i][j];        if(b[i][j]>Mab[i])Mab[i]=b[i][j];    }    printf("%d",Ans);    return 0;}
bzoj1723

 

阅读全文
0 0