F. 生命(菱形转矩阵+二维前缀和)

44 篇文章 1 订阅
40 篇文章 0 订阅


思路:模拟发现是菱形,转化到矩形,然后跑矩形的二位前缀和

#include<iostream>
#include<vector>
#include<queue>
#include<cstring>
#include<cmath>
#include<map>
#include<set>
#include<cstdio>
#include<algorithm>
#define debug(a) cout<<#a<<"="<<a<<endl;
using namespace std;
const int maxn=1500;
typedef int LL;
inline LL read(){LL x=0,f=1;char ch=getchar();	while (!isdigit(ch)){if (ch=='-') f=-1;ch=getchar();}while (isdigit(ch)){x=x*10+ch-48;ch=getchar();}
return x*f;}
LL a[maxn][maxn],b[maxn*2][maxn*2],c[maxn*2][maxn*2];
LL sum[maxn*2][maxn*2];
int main(void)
{
  LL n,k,q;n=read();k=read();q=read();
  /*
  for(LL i=1;i<=n;i++){
    for(LL j=1;j<=n;j++){
        cin>>a[i][j];
    }
  }*/
  for(LL i=1;i<=k;i++){
    LL x,y;x=read();y=read();
    a[x][y]++;
  }
  /*
  for(LL i=1;i<=n;i++){
    for(LL j=1;j<=n;j++){
        cout<<a[i][j];
    }
    cout<<"\n";
  }*/
  for(LL i=1;i<=n;i++){
    for(LL j=1;j<=n;j++){
        c[i-j+n][i+j]=a[i][j];
    }
  }
  LL m=n*2;
  /*
  for(LL i=1;i<=m;i++){
    for(LL j=1;j<=m;j++){
        cout<<c[i][j]<<" ";
    }
    cout<<"\n";
  }*/
  for(LL i=1;i<=m;i++){
    for(LL j=1;j<=m;j++){
        sum[i][j]=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1]+c[i][j];
    }
  }
  while(q--){
    LL r;r=read();
    LL ans=0;
    for(LL i=1;i<=n;i++){///枚举中心点
        for(LL j=1;j<=n;j++){
            LL x1=i-r;LL y1=j;///原矩阵菱形的最上角
            LL x2=i+r;LL y2=j;///原矩阵菱形的最下角
            LL left_up_x=x1-y1+n;LL left_up_y=x1+y1;
            LL right_down_x=x2-y2+n;LL right_down_y=x2+y2;
            if(left_up_x<1) left_up_x=1;
            if(left_up_y<1) left_up_y=1;
            if(right_down_x>m) right_down_x=m;
            if(right_down_y>m) right_down_y=m;
         ///   debug(left_up_x);debug(left_up_y);
         ///   debug(right_down_x);debug(right_down_y);
            ans=max(ans,sum[right_down_x][right_down_y]-sum[right_down_x][left_up_y-1]-sum[left_up_x-1][right_down_y]+sum[left_up_x-1][left_up_y-1]);
          ///  debug(ans);
        }
    }
    printf("%lld\n",ans);
  }
  /*
  for(LL i=1;i<=n;i++){
    for(LL j=1;j<=n;j++){
        b[i+j-1][n-i+j]=a[i][j];///顺时针45°
    }
  }
  for(LL i=1;i<=n;i++){
    for(LL j=1;j<=n;j++){
        c[i-j+n][i+j]=a[i][j];///逆时针45°
        ///c[i+j][i-j+n]=a[i][j];//(这个是斜45°按输入顺序输出)
    }
  }
  cout<<"\n";
  LL m=2*n-1;
  for(LL i=1;i<=m;i++){
    for(LL j=1;j<=m;j++){
        cout<<b[i][j]<<" ";
    }
    cout<<"\n";
  }
  LL s=2*n;
  cout<<"\n";
  for(LL i=1;i<=s;i++){
    for(LL j=1;j<=s;j++){
        cout<<c[i][j]<<" ";
    }
    cout<<"\n";
  }*/
return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值