zoukankan      html  css  js  c++  java
  • 环状二维数组最大子数组求和

    题目:返回一个二维整数数组中最大子数组的和。要求:输入一个二维整形数组,数组里有正数也有负数。二维数组首尾相接,象个一条首尾相接带子一样。

    n数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和。求所有子数组的和的最大值。要求时间复杂度为O(n)。
     

    结对编程要求: 两人结对完成编程任务。 一人主要负责程序分析,代码编程。

                        一人负责代码复审和代码测试计划。

                       发表一篇博客文章讲述两人合作中的过程、体会以及如何解决冲突(附结对开发的工作照)。

    结对开发过程:

        这次的编程开发是基于上次的以为数组,我和我的搭档@天使RL恶魔开始了认真的讨论,再结合课堂上的同学讨论,如何能在二维数组原有的基础上,加上首尾相连这个条件,同时降低时间复杂度,这种方法的大概思想是:遍历数组里面的每一个数将第一个数变为最后一个数,具体算法 a[i][j-1]=a[i][j],这样又变成了一个新的二维数组,输出每个数组的最大子数组和,然后比较每个输出的和,找出最大的数。

    程序代码:

      1 #include <iostream>
      2 using namespace std;
      3 
      4 int maxSubArray(int **a,int n,int m)
      5 {
      6   int **p=new int*[n];
      7   int i,j;
      8   if(m==0||n==0)
      9     return 0;
     10   //计算p[i][j]    
     11   for(i=0;i<n;i++)
     12   {
     13     p[i]=new int[m];
     14     for(j=0;j<m;j++)
     15     {
     16       if(i==0)
     17       {
     18         if(j==0)
     19           p[i][j]=a[i][j];
     20         else
     21           p[i][j]=p[i][j-1]+a[i][j];
     22       }
     23       else
     24       {
     25         if(j==0)
     26           p[i][j]=p[i-1][j]+a[i][j];
     27         else
     28           p[i][j]=p[i][j-1]+p[i-1][j]-p[i-1][j-1]+a[i][j];
     29       }
     30     }
     31   }
     32   //计算二维数组最大子数组的和
     33   int temp;
     34   int max=a[0][0];
     35   int ans;
     36   //如果m==1
     37   if(m==1)
     38   {
     39     for(i=0;i<n;i++)
     40     {
     41       for(j=i;j<n;j++)
     42       {
     43         if(i==0)
     44         {
     45           temp=p[j][m-1];
     46         }
     47         else
     48         {
     49           temp=p[j][m-1]-p[i-1][m-1];
     50         }
     51         if(ans<temp)
     52           ans=temp;
     53       }
     54     }
     55   }
     56   else
     57   {
     58     for(i=0;i<n;i++)
     59     {
     60       for(j=i;j<n;j++)
     61       {
     62         if(i==0)
     63         {
     64           temp=p[j][m-1]-p[j][m-2];
     65         }
     66         else
     67         {
     68           temp=p[j][m-1]-p[j][m-2]-p[i-1][m-1]+p[i-1][m-2];
     69         }
     70         for(int k=m-2;k>=0;k--)
     71         {
     72           if(temp<0)
     73             temp=0;
     74           if(i==0)
     75           {
     76             if(k==0)
     77               temp+=p[j][k];
     78             else
     79               temp+=p[j][k]-p[j][k-1];
     80           }
     81           else
     82           {
     83             if(k==0)
     84               temp+=p[j][k]-p[i-1][k];
     85             else
     86               temp+=p[j][k]-p[j][k-1]-p[i-1][k]+p[i-1][k-1];
     87           }
     88           if(ans<temp)
     89             ans=temp;
     90         }
     91       }
     92     }
     93   }
     94   return ans;
     95 }
     96 
     97 int main()
     98 {
     99   int n,m,temp;
    100   int a1,a2;
    101   int k=0;
    102   printf("请输入二维数组的行数和列数:
    ");
    103   scanf("%d %d",&n,&m);
    104   int i,j;
    105   int **a=new int*[n];
    106   printf("请输入%d*%d个二维数组元素:
    ",n,m);
    107   for(i=0;i<n;i++)
    108   {
    109     a[i]=new int[m];
    110 
    111     for(j=0;j<m;j++)
    112     {
    113       scanf("%d",&a[i][j]);
    114     }
    115   }
    116   int ans=maxSubArray(a,n,m);
    117   printf("二维数组的最大子数组之和是:%d
    ",ans);
    118  for(a2=0;a2<m-1;a2++) 
    119  { for(i=0;i<n;i++)
    120   {   temp=a[i][0];
    121       for(j=1;j<m;j++)
    122       {a[i][j-1]=a[i][j];}
    123       a[i][m-1]=temp;
    124   }
    125    
    126     for(i=0;i<n;i++)
    127   {   
    128       for(j=0;j<m;j++)
    129       {   
    130          
    131           if(k%m==0) 
    132           {cout<<endl;}
    133           cout<<a[i][j]<<" ";
    134              k++;
    135       }
    136       
    137   }
    138   
    139   a1=maxSubArray(a,n,m);
    140   printf("二维数组的最大子数组之和是:%d
    ",a1);
    141  }
    142   return 0;
    143 }

     程序运行截图:

    总结感受:

      在程序设计之前应该与之前的环状一位数组相联系,我们使用了相同的方法解决了问题。同样的由最后一列移到第一列,前面几列依次向后移,有n列就移n-1次,求出n个矩阵的最大子数组,进而在算出环状二维数组的最大子数组。

  • 相关阅读:
    December 23rd 2016 Week 52nd Friday
    December 22nd 2016 Week 52nd Thursday
    December 21st 2016 Week 52nd Wednesday
    December 20th 2016 Week 52nd Tuesday
    December 19th 2016 Week 52nd Sunday
    December 18th 2016 Week 52nd Sunday
    uva294(唯一分解定理)
    uva11624Fire!(bfs)
    fzu2150Fire Game(双起点bfs)
    poj3276Face The Right Way
  • 原文地址:https://www.cnblogs.com/cainiao1hao/p/4397394.html
Copyright © 2011-2022 走看看