AcWing 3316. 吃豆人
原题链接
中等
作者:
江见月
,
2021-04-17 18:23:04
,
所有人可见
,
阅读 361
//吃豆人
/*
解题思路:
分析吃豆人运行轨迹 我们会发现吃豆人会走一个环形的路径 或者 直线
枚举两个环的顶部落点 去掉交点 保留最大值即可
*/
#include <bits/stdc++.h>
using namespace std;
const int N = 1010;
int n;
int g[N][N],flag[N][N];
int s[N];
struct point{
int x;
int y;
};
int main( )
{
cin >> n;
//读入所有点
for(int i = 0; i < n; i++)
for(int j = 0; j < n; j++)
cin >> g[i][j];
//处理对角线
for(int i = 0; i < n; i++ )
{
s[0] += g[i][i];
s[n-1] += g[i][n-1-i];
}
int dx[4] = {1, 1, -1, -1},dy[4] = {-1, 1, 1, -1};
//处理处所有的环的数字和
for(int i = 1;i < n - 1; i++ )
{
int x = 0, y = i, d = 0;
for(int j = 0; j < (n - 1) * 2; j++)
{
s[i] += g[x][y];
int a = x + dx[d], b = y + dy[d];
if(a < 0 || a >= n || b < 0 || b >= n )
{
d = (d + 1) % 4;//换方向
a = x + dx[d], b = y + dy[d];
}
x = a, y = b;
}
}
//枚举吃豆人在顶部的吃豆位置 交点个数可能为 0 2 4 去点其中重复计算的交点
int res = 0;
for(int i = 0; i < n; i++ )
for(int j = i + 1; j < n; j++)
{
//环上 点的奇偶性不同 不存在交点
if ((j - i) % 2) res =max(res, s[i] + s[j]);
else //存在交点 要减去被重复计算的点
{
int sum = s[i] + s[j];
set<point> S;
int x = (j - i) / 2, y = i + x;
if(flag[x][y]==0)
{
sum -= g[x][y];
flag[x][y] = 1;
}
if(flag[y][x]==0)
{
sum -= g[y][x];
flag[y][x] = 1;
}
int a = n - 1 - y, b = n - 1 - x;
if(flag[a][b]==0)
{
sum -= g[a][b];
flag[a][b] = 1;
}
if(flag[b][a]==0)
{
sum -= g[b][a];
flag[b][a] = 1;
}
flag[a][b]=flag[b][a]=flag[x][y]=flag[y][x]=0;//还原
res = max(res, sum);
}
}
cout<<res;
return 0;
}