关于一道题的一点疑问和讨论
  • 板块学术版
  • 楼主SalomeJLQ
  • 当前回复13
  • 已保存回复13
  • 发布时间2020/9/30 20:41
  • 上次更新2023/11/5 12:22:24
查看原帖
关于一道题的一点疑问和讨论
246979
SalomeJLQ楼主2020/9/30 20:41

就是这题

写了半天调了半天,最后迫不得已才看了题解,结果问号越来越多。


首先,就是题解中的求正方形面积那部分中,两层循环都是从r-1开始的,但是内部的语句中的下标出现了sum[i-1],请问这样的话,第一次循环的时候不就会出现下标是-1的越界情况吗?


其次,两份意义完全相同的代码,为什么分数不同?

我仅仅是把

	for(int i=m;i<5005;i++)
		for(int j=m;j<5005;j++)
			ans=maxn(ans,s[i][j]-s[i-m][j]-s[i][j-m]+s[i-m][j-m]);

改成了

	for(int i=m;i<5005;i++)
		for(int j=m;j<5005;j++)
			if(s[i][j]-s[i-m][j]-s[i][j-m]+s[i-m][j-m]>ans)
				ans=s[i][j]-s[i-m][j]-s[i][j-m]+s[i-m][j-m];

为什么分数从91骤减至55?


然后,我把上面那段代码中循环的范围,按照题解的m-1之后,为什么就几乎全部WA了?

所以到底是我的程序出了问题,还是我和题解的思路是不同的,或者题解出错了?

(不敢交题解,怕棕)


最后附上我没看题解前的编写程序的历程。

第一份64分,部分MLE,第八个点WA

#include<bits/stdc++.h>
using namespace std;
int a[5005][5005],s[5005][5005],n,m,x,y,v,ans;
int main(){
    cin>>n>>m;
    for(int i=1;i<=n;i++){cin>>x>>y>>v;a[x][y]=v;}
    for(int i=1;i<5005;i++)
        s[0][i]=s[0][i-1]+a[0][i],s[i][0]=s[i-1][0]+a[i][0];
    for(int i=1;i<5005;i++)
        for(int j=1;j<5005;j++)
            s[i][j]=s[i-1][j]+s[i][j-1]-s[i-1][j-1]+a[i][j];
    for(int i=m;i<5005;i++)
        for(int j=m;j<5005;j++)
            ans=max(ans,s[i][j]-s[i-m][j]-s[i][j-m]+s[i-m][j-m]);
    cout<<ans;
    return 0;
}

第二份55分,改成short,然后强制类型转换(否则编译错误)。

WA了好几个点。

#include<bits/stdc++.h>
using namespace std;
short a[5005][5005],s[5005][5005],n,m,x,y,v,ans;
int main(){
    cin>>n>>m;
    for(int i=1;i<=n;i++){cin>>x>>y>>v;a[x][y]=v;}
    for(int i=1;i<5005;i++)
        s[0][i]=s[0][i-1]+a[0][i],s[i][0]=s[i-1][0]+a[i][0];
    for(int i=1;i<5005;i++)
        for(int j=1;j<5005;j++)
            s[i][j]=s[i-1][j]+s[i][j-1]-s[i-1][j-1]+a[i][j];
    for(int i=m;i<5005;i++)
        for(int j=m;j<5005;j++)
            ans=max(int(ans),int(s[i][j]-s[i-m][j]-s[i][j-m]+s[i-m][j-m]));
    cout<<ans;
    return 0;
}

然后手写max函数,第八个点WA,其他AC

#include<bits/stdc++.h>
using namespace std;
short a[5005][5005],s[5005][5005],n,m;int x,y,v,ans;
short maxn(short a,short b){return a>b?a:b;}
int main(){
    cin>>n>>m;
    for(int i=1;i<=n;i++){cin>>x>>y>>v;a[x][y]=v;}
    for(int i=1;i<5005;i++)
        s[0][i]=s[0][i-1]+a[0][i],s[i][0]=s[i-1][0]+a[i][0];
    for(int i=1;i<5005;i++)
        for(int j=1;j<5005;j++)
            s[i][j]=s[i-1][j]+s[i][j-1]-s[i-1][j-1]+a[i][j];
    for(int i=m;i<5005;i++)
        for(int j=m;j<5005;j++)
            ans=maxn(ans,s[i][j]-s[i-m][j]-s[i][j-m]+s[i-m][j-m]);
    cout<<ans;
    return 0;
}

然后maxn函数返回值强制类型转换,并且修改返回值类型。

评测结果同上。

#include<bits/stdc++.h>
using namespace std;
short a[5005][5005],s[5005][5005],n,m;int x,y,v,ans;
int maxn(short a,short b){return int(a>b?a:b);}
int main(){
    cin>>n>>m;
    for(int i=1;i<=n;i++){cin>>x>>y>>v;a[x][y]=v;}
    for(int i=1;i<5005;i++)
        s[0][i]=s[0][i-1]+a[0][i],s[i][0]=s[i-1][0]+a[i][0];
    for(int i=1;i<5005;i++)
        for(int j=1;j<5005;j++)
            s[i][j]=s[i-1][j]+s[i][j-1]-s[i-1][j-1]+a[i][j];
    for(int i=m;i<5005;i++)
        for(int j=m;j<5005;j++)
            ans=maxn(ans,s[i][j]-s[i-m][j]-s[i][j-m]+s[i-m][j-m]);
    cout<<ans;
    return 0;
}

然后看到了ans不会超过short,所以直接全改short。

评测结果同上。

#include<bits/stdc++.h>
using namespace std;
short a[5005][5005],s[5005][5005],n,m,x,y,v,ans;
short maxn(short a,short b){return a>b?a:b;}
int main(){
    cin>>n>>m;
    for(int i=1;i<=n;i++){cin>>x>>y>>v;a[x][y]=v;}
    for(int i=1;i<5005;i++)
        s[0][i]=s[0][i-1]+a[0][i],s[i][0]=s[i-1][0]+a[i][0];
    for(int i=1;i<5005;i++)
        for(int j=1;j<5005;j++)
            s[i][j]=s[i-1][j]+s[i][j-1]-s[i-1][j-1]+a[i][j];
    for(int i=m;i<5005;i++)
        for(int j=m;j<5005;j++)
            ans=maxn(ans,s[i][j]-s[i-m][j]-s[i][j-m]+s[i-m][j-m]);
    cout<<ans;
    return 0;
}
2020/9/30 20:41
加载中...