吐槽:首先我真的对自己无语到了极点,就因为写错了一个坐标卡了一个半小时。
问题:此题就是及其简单的贪心的题目,比赛开始没多久,AC了第一题以后就想出来该怎么做了,但是因为写错了一个坐标,每次都是WA。
注意:其次还要注意数据范围,数据范围是1e3,如果用数组来存每个有鱼的点到四个角的坐标的曼哈顿距离,考虑极端情况,全部都有鱼的话点的数量就是1e3乘以1e3=1e6,而四个角到每个点的曼哈顿距离就有4乘以1e6,如果存距离的数组只开1e3就会发生数组越界。
方法一:比赛代码(待优化)
#include<bits/stdc++.h>
using namespace std;
const int N=1010;
int n,m;
char g[N][N];
vector<pair<int ,int>> ve;
int dis[N];//第二个错误,数组范围开小了,应该是int dis[4*1000010]
int main()
{
cin>>n>>m;
int pos[4][2]={{0,0},
{0,m-1},
{0,n-1},//错误就在这应该是n-1,0,因为这里表达的是四个角的坐标
{n-1,m-1}};//上左,上右,下左,下右
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
cin>>g[i][j];
if(g[i][j]=='#')
ve.push_back({i,j});
}
}
int t=0;
for(int i=0;i<ve.size();i++){
for(int j=0;j<4;j++){
dis[t++]=abs(ve[i].first-pos[j][0])+abs(ve[i].second-pos[j][1]);
}
}
sort(dis,dis+t,greater<int>());
cout<<dis[0];
//for(auto i:ve)cout<<i.first<<' '<<i.second;
//for(int i:dis)cout<<i<<' ';
return 0;
}
方法二:其实这题根本就不要用数组,不用存数据,只是需要知道最大值即可,有些题用数组可能会出现内存超出限制MLE,因此及时计算及时判断最大值就可以了。
#include<bits/stdc++.h>
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
using namespace std;
int n,m,ans;
int main()
{
IOS;
cin>>n>>m;
string s[n+10];//使用了字符串类的数组,如果数据范围过大可能普通数组不行
for(int i=0;i<n;i++)cin>>s[i];
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
if(s[i][j]=='#'){
ans=max(ans,i+j);
ans=max(ans,i+m-1-j);
ans=max(ans,(n-1-i)+j);
ans=max(ans,(n-1-i)+(m-1-j));
}
}
}
cout<<ans<<'\n';
return 0;
}
方法三:使用字符串类型的vector也可以
#include<bits/stdc++.h>
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
using namespace std;
int n,m,ans;
int main()
{
IOS;
cin>>n>>m;
vector<string> s(n+10);
for(int i=0;i<n;i++)cin>>s[i];
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
if(s[i][j]=='#'){
ans=max(ans,i+j);
ans=max(ans,i+m-1-j);
ans=max(ans,(n-1-i)+j);
ans=max(ans,(n-1-i)+(m-1-j));
}
}
}
cout<<ans<<'\n';
return 0;
}
方法四:这种方法使用内存最少,没有使用数组
#include<bits/stdc++.h>
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
using namespace std;
int n,m,ans;
char ch;
int main()
{
IOS;
cin>>n>>m;
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
cin>>ch;
if(ch=='#'){
ans=max(ans,i+j);
ans=max(ans,i+m-1-j);
ans=max(ans,(n-1-i)+j);
ans=max(ans,(n-1-i)+(m-1-j));
}
}
}
cout<<ans<<'\n';
return 0;
}
感悟:其实诸如此类有关坐标的题,从一开始比较好理解,在边界的时候不容易错,例如从零开始,求曼哈顿距离的时候是abs(n-1-i)+abs(m-1-j),而从一开始则为abs(n-i)+abs(m-j),能不用数组尽量不用,比如求最值的时候,或者不需要使用出现过的数据,不用存储数据优先考虑不用数组