UVA108的加强版,这是像是个圆环,所以还是沿用108的方法,首先二维数组转化为一维数组,然后就是对这个特殊圆环的处理,这一部分代码写的比较乱。
1 | -1 | 0 | 0 | -4 |
2 | 3 | -2 | -3 | 2 |
4 | 1 | -1 | 5 | 0 |
3 | -2 | 1 | -3 | 2 |
-3 | 2 | 4 | 1 | -4 |
另外,最内层fot循环计算一维最大连续和时,用到了这样的知识:n=5的数组,最大连续和有两种情况,一种是在n=1到5这个区间内,第二种是在,比如是n=4到n=1这样的区间上,就无法用108那种方法找maxsum了,但是这样n=2到n=3这个区间的和一定是最小的,所以求出n=1到n=5的和sum,和这一部分的最小连续和minsum,
maxsum=max(maxsum,sum-minsum);找出maxsum.
WA了一次是因为sum,和minsum的计算只在在h<n时。
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
//freopen("in.txt","r",stdin);
int cas,n,start,end,temp,mintemp,sum;
int num[80][80],rowsum[80],maxsum,minsum;
scanf("%d",&cas);
while(cas--)
{
scanf("%d",&n);
for(int i=0; i<n; i++)
{
for(int j=0; j<n; j++)
scanf("%d",&num[i][j]);
}
maxsum=num[0][0];
for(int i=0; i<n; i++)
{
memset(rowsum,0,sizeof(rowsum));
for(int j=i; ; j++)
{
int hj=j;
if((i==0||i==1)&&j==n)
break;
else if(j==n+i-1&&j>=n) break;
hj=j%n;
for(int k=0; k<n; k++)
rowsum[k]+=num[hj][k];
temp=rowsum[0];
start=end=0;
minsum=mintemp=sum=rowsum[0];
for(int h=1; h<2*n; h++)
{
if(h<n)
sum+=rowsum[h];
int hg=h%n;
if(temp<0)
{
start=hg;
temp=0;
}
if(mintemp>0)
mintemp=0;
temp+=rowsum[hg];
if(h<n)
mintemp+=rowsum[hg];
minsum=min(mintemp,minsum);
if(temp>=maxsum)
{
end=hg;
maxsum=temp;
}
if((start==0||start==1)&&h==n-1)
break;
else if(h==n+start-2&&h>=n)
break;
}
maxsum=max(maxsum,sum-minsum);
}
}
cout<<maxsum<<endl;
}
return 0;
}