1、题目要求:
返回一个二维数组中最大连通子数组的和
从input.txt 文件中读入一个二维整形数组,数组里有正数也有负数。
2、实现思路:
(1)先要能够读入txt 文档中的各数的值;
(2)将读出的行数、列数、数组中的数分别保存;
(3)每一行都存在一个最大的子数组和;
(4)将每行最大的子数组和以最小的代价连接起来,将代价与各个和加在一起,可以得出最大值
3、思路整理(实现步骤):
(1)读入txt 文档中的各数的值,第一行是行数,存给 line ,第二行是列数,存到row,剩下的数存入数组array【】【】中;
(2)从第一行开始,按照前几次实验的方法,找出每一行中的最大子数组和,存入array2【】中;并找到这个最大子数组和的数组的最小下标min_i 和最大下标max_i 分别存入mini【】和maxi【】中;
(3)将每一行中的最大最小下标与下一行的最小最大下标相比,联通,则这两行的最大子数组和为两行的最大子数组和相加;
(4)若不能联通,选择一个最小代价路径使其联通;
(5)看有无其他的正数与这一条联通的线相连,若有,加到总和上。
4、源代码:
1 #include <iostream> 2 #include <fstream> 3 #include <string> 4 using namespace std ; 5 6 7 int maxcount(int n,int a[],int *min_i,int *max_i)//求一行中的最大子数组和 8 { 9 int b[100]={0}; 10 int i,sum=0,max=0; 11 for(i=0;i<n;i++) 12 { 13 if(sum<0) 14 { 15 sum=a[i]; 16 } 17 else 18 { 19 sum=sum+a[i]; 20 } 21 b[i]=sum; 22 } 23 max=b[0]; 24 for(i=0;i<n;i++) 25 { 26 if (max<b[i]) 27 { 28 max= b[i]; 29 *max_i = i; 30 } 31 } 32 for (i = *max_i;i >= 0;i--) 33 { 34 if (b[i] == a[i]) 35 { 36 *min_i = i; 37 break; 38 } 39 } 40 return max; 41 } 42 43 44 int main() 45 { 46 int i,j; 47 char str[1024] ; 48 ifstream infile( "D:\input.txt" );//文件位置 49 if ( !infile.good() ) 50 { 51 cout <<" 打开文件“D:\input.txt”失败! 请检查文件路径下是否存在该文件! " ; 52 return -1; 53 } 54 int line,row; 55 int array[100][100],array2[100];//数组array 是二维数组,array2 是每行的最大子数组和组成的数组 56 infile.getline( str, sizeof(str) );//获取行数 57 sscanf( str , "%d" , &line); 58 infile.getline( str, sizeof(str) );//获取列数 59 sscanf( str , "%d" , &row ); 60 cout <<" 二维数组共 "<< line <<" 行 "<< row<<" 列"<<endl<<endl; 61 cout <<" 二维数组: "<< endl; 62 for(i=0;i<line;i++)//读取二维数组 63 { 64 for(j=0;j<row;j++) 65 { 66 infile>>array[i][j]; 67 } 68 } 69 for(i=0;i<line;i++)//输出二维数组 70 { 71 cout <<" "; 72 for(j=0;j<row;j++) 73 { 74 cout << array[i][j]<<" " ; 75 } 76 cout <<endl; 77 } 78 infile.close(); 79 80 81 int min_i; 82 int max_i;//最大子数组和数的下标 83 int countmax;//最大子数组的和数的下标 84 int sum,max; 85 int mini[100],maxi[100],t[100]; 86 for(i=0;i<line;i++) 87 { 88 for(j=0;j<row;j++) 89 { 90 array2[j]=array[i][j]; 91 } 92 sum=maxcount(row,array2,&min_i,&max_i); 93 mini[i]=min_i; // 保存最大和子数组的最小下标 94 maxi[i]=max_i; // 保存最大和子数组的最大下标 95 t[i]=sum; 96 } 97 countmax=t[0]; 98 for(i=0;i+1<line;i++) 99 { 100 if(mini[i]<=maxi[i+1] && maxi[i]>=mini[i+1]) 101 { 102 countmax+=t[i+1]; 103 } 104 105 for(j=mini[i];j<mini[i+1];j++) 106 { 107 if(array[i+1][j]>0) //判别剩下的单独正数 108 { 109 countmax+=array[i+1][j]; 110 } 111 } 112 } 113 cout<<" 最大联通子数组和为:"<<countmax<<endl<<endl; 114 return 0; 115 }
5、运行结果:
项目计划日志(单位:h):
听课 | 编写程序 | 阅读相关书籍 | 网上查找资料 | 日总计 | |
周六 | 0 | 2 | 0 | 0.5 | 2.5 |
周日 | 0 | 2 | 1 | 1 | 4 |
周一 | 0 | 2 | 0 | 1 | 3 |
时间记录日志(单位:min):
日期 | 开始时间 | 结束时间 | 中断时间 | 净时间 | 活动 | 备注 |
星期六 | 8:00 | 11:30 | 30(洗漱) | 150 | 查资料,编程 | |
星期日 | 8:30 | 11:00 | 140 | 查资料,编程 | ||
15:00 | 18:00 | 100 | 编程 | |||
星期一 | 8:30 | 11:00 | 160 | 查资料,编程 |