【洛谷 P7472】【NOI Online 2021 入门组]】吃豆人
题目
解题思路
手推一下会发现
镜面反射会形成回路或者对角线
求出以第一行中任一点所形成的回路或对角线
枚举两两之间的和
减去重复的点即可
根据反射出来的矩形的奇偶性可得
所谓奇偶性,就是矩形在第一行的点的差值为奇则无交点,为偶则有
两个矩形之间是否有交点
自己手推规律吧
😃
代码
#include<iostream>
#include<cstdio>
using namespace std;
int n,ans,sum[1010],zx[1002][1002],yx[1002][1002],a[1002][1002];
int answer(int x)
{
int ans=0,y=n;
if (x==1) return zx[n][n];
if (x==n) return yx[n][1]; //对角线直接取
ans+=yx[x][1];
ans-=a[1][x]+a[x][1]; //顶点会多累加一次所以要减去
x=n-x+1;
ans+=zx[x][y]+zx[y][x]+yx[y][x];
ans-=a[x][y]+a[y][x];
return ans;
}
int cf(int x,int y)
{
if ((x-y)%2!=0) return 0; //没有交点
if (x==1&&y==n) //两条对角线
if (n%2)
return a[(n+1)/2][(n+1)/2];
else return 0;
if (x==1) return a[(y+1)/2][(y+1)/2]+a[(2*n-y+1)/2][(2*n-y+1)/2]; //左边对角线+矩形
if (y==n) return a[(n-x)/2+1][(n+x)/2]+a[(n+x)/2][(n-x)/2+1]; //右边对角线+矩形
return a[(x+y)/2][(y-x)/2+1]+a[(y-x)/2+1][(x+y)/2]+a[n-(y-x)/2][n-(x+y)/2+1]+a[n-(x+y)/2+1][n-(y-x)/2]; //两个矩形
}
int main()
{
scanf("%d",&n);
for (int i=1;i<=n;i++)
for (int j=1;j<=n;j++)
scanf("%d",&a[i][j]);
for (int i=1;i<=n;i++)
for (int j=1;j<=n;j++)
{
zx[i][j]=a[i][j]+zx[i-1][j-1];
yx[i][j]=a[i][j]+yx[i-1][j+1];
} //预处理出左斜和右斜一线的值
for (int i=1;i<=n;i++)
sum[i]=answer(i); //得出回路或对角线的值
for (int i=1;i<=n;i++)
for (int j=i+1;j<=n;j++)
ans=max(ans,sum[i]+sum[j]-cf(i,j)); //枚举两两之间的和
printf("%d",ans);
return 0;
}