经过漫漫漫~~~~~~~~~~~~~~长的编译和调试,第二次作业终于告一段落了

先放出源码,思路后面慢慢道来

#include<stdio.h>
#include<stdlib.h>
int find(int num,int &s,int &max)
{
  s+=num; 
  if(s<num)s=num;
  if (max<s) max=s;

}

int main()
{
    int s,max;
    int x,y,a[100][100],b[1000][100],i,j,t,n,sum,flag=0;
    char c;
    freopen("input.txt","r",stdin);   
    freopen("output.txt","w",stdout);
    scanf("%d",&y);
    scanf("%d",&x);
    for(i=0;i<y;i++)
    {
        for(j=0;j<x-1;j++)
        {        
        if (!(scanf("%d",&a[i][j])))  flag=-1; 
        scanf("%c",&c);
        if (c!=',') flag=-1; 
        }
    scanf("%d",&a[i][x-1]);
    }
   for(i=0;i<x;i++)
   {
   n=0;
       for(j=0;j<y;j++)
       {
       sum=0;
           for(t=j;t>=0;t--)
           {           
           sum=sum+a[t][i]; 
           b[n][i]=sum;
           n++;          
           }

       }
   }
   max=b[0][0];
   for(i=0;i<1000;i++)
   {
   s=b[i][0];
        for(j=1;j<x;j++)
        find(b[i][j],s,max);
   }
   if (flag==-1) printf("error!");
   else   printf("%d",max);
            
}
 

以下是测试过程截图

input.TXT内容如下

输出结果为28,放在同文件夹下的output.txt

 

 

算法的实现原理:

在刚接手这个题目的时候,我无从下手,不知道如何将一个一维的序列脱战到二维。

几番思考后,我仔细观察了结构,发现任何二位的图形其实可以压缩成为一维的一条线——这就是我解开这道题目谜底的方法

也就是说在二位的纵轴上,我把各行数字分别求和,让这个二位数组的任何情况都化简为一维数组来处理,这样答案就显而易见了

关键代码是如下这段

   for(i=0;i<x;i++)
   {
   n=0;
       for(j=0;j<y;j++)
       {
       sum=0;
           for(t=j;t>=0;t--)
           {           
           sum=sum+a[t][i]; 
           b[n][i]=sum;
           n++;          
           }

       }
   }

这是将二维数组逐行求和,并将得到的新的“和数组”,也可以叫“压缩数组”放在新建的数组b中

数组b的行数需要很大,以便存下所有的a的行数的组合情况,然而列数只需要保持与数组a相等即可

举个简单的例子来说

比如有个输入是:

2

3

1,2,3

4,5,6

那么我在进行压缩数组以后,得到的数组b为

1,2,3

4,5,6

5,7,9

很显然可以看到,第三行5,7,9是第一行和第二行的和

在计算矩阵的子序列和的时候只需要逐行计算子序列的和

当计算到5,7,9 的和的时候实际上是在计算

1,2,3

4,5,6

这两个数组的和

这就是我“压缩矩阵”思路的原理

int find(int num,int &s,int &max)
{
  s+=num; 
  if(s<num)s=num;
  if (max<s) max=s;

}

这段代码是一维数组的动态规划,只需要将数组b中的一行取出,套用这个动态规划算法得到改行数组的最大值,并b数组中所有行的最大值取最大,就是最终的答案

关于错误输入返回error,我设计了一种输入的行数或者列数大于你已经输入的行数或者列数的情况

for(i=0;i<y;i++)
    {
        for(j=0;j<x-1;j++)
        {        
        if (!(scanf("%d",&a[i][j])))  flag=-1; 
        scanf("%c",&c);
        if (c!=',') flag=-1; 
        }
    scanf("%d",&a[i][x-1]);
    }

flag=-1时,返回error,其他情况返回答案

当然,还有行数或者列数小于你已经输入的行数或者列数的情况,我没有找到好的方法实现,就仅此而已。

综上,这个算法已经能够解决第二题的二维矩阵,对于第一题的一维矩阵这种特例就更不在话下了

因此第一第二题得到了解决

第三题百思得不到其解,只能放弃!

第四、五题解法已经有了答案

这两道题目看似是三维方向的拓展,其实仔细想想就是一个简单的二维问题的延伸

所谓的头尾相接,上下相接,轮胎形状,这些只需要我们在二维矩阵上面做些文章即可

也就是把原有的二维矩阵拓展成为4个二维矩阵,即把原有矩阵纵向复制一份,使它上下相接,横向复制一份使它左右相连,对角线方向复制一份,即可构成轮胎状。

程序代码还是上面的代码

只是在的A[I][J]上做做手脚,变成A[2I][2J],按上面的方法进行拓展,得到的A[2I][2J]再利用程序进行计算即可。

拿例子来说

这是老师给出的一个原始矩阵

我将它拓展为

 

只需要运算下面这张拓展矩阵就能得到“轮胎”的正确答案了

 

注:在运算的过程中我们要有个限制就是在拓展矩阵中得到的最大的矩阵是x行*y列,超过这个的为错误

在计算压缩矩阵的时候需要相应的限制即可

 

 

这是我第二次作业,可能有各种各样的漏洞,但是确实是用心,花了不少时间去做的,希望助教老师给我一个满意的分数,谢谢老师,辛苦了