、题目及要求:
题目:
返回一个二维整数数组中最大子数组的和。
要求:
输入一个二维整形数组,数组里有正数也有负数。
二维数组首尾相接,象个一条首尾相接带子一样。
数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和。
求所有子数组的和的最大值。
二、解题思路:
因为是二维数组首尾相连,所以将两个同样的数组首尾相接合并成一个数组,在用以前求二维数组最大子数组的方法求解(求一行的最大值子数和,然后把下一行的加在这一行上,求最大子数组和,与之前的比较,最大的存放在最大数里,直到加到最后一行,从第一行开始进行直到第二行)。
4 #include<iostream>
5 #include<fstream>
6 #include<ctime>
7 using namespace std;
8 #define N 100
9
10 typedef struct
11 {
12 int dian[N];
13 int xian[N][N];
14 int diannum;//数组中元素个数
15 }Tu;//图
16
17 void set(Tu &shuzu, int x, int y)
18 {
19 int i, j;
20 fstream infile("input.txt", ios::in); //打开指定文件
21 if (!infile)
22 {
23 cout << "open error!" << endl;
24 exit(1);
25 }
26 infile >> x >> y; //从文件中读取数组行数和列数
27 shuzu.diannum = x*y;
28 for (i = 1; i <= shuzu.diannum; i++)//从文件中读取数组元素
29 {
30 infile >> shuzu.dian[i];
31 }
32 infile.close();
33
34 for (i = 1; i <= shuzu.diannum; i += y)
35 {
36 for (j = i; j <= i + y - 2; j++)
37 {
38 shuzu.xian[j][j + 1] = 1;
39 shuzu.xian[j + 1][j] = 1;
40 }
41 }
42 for (i = 1 + y; i<shuzu.diannum; i += y)
43 {
44 for (j = i; j <= i + x - 1; j++)
45 {
46 shuzu.xian[j][j - y] = 1;
47 shuzu.xian[j - y][j] = 1;
48 }
49 }//将一维数组转换成二维图的形式
50 }
51
52 void output(Tu shuzu)//以图的形式输出数组
53 {
54 for (int i = 1; i <= shuzu.diannum; i++)
55 {
56 cout << shuzu.dian[i];
57 if (shuzu.xian[i][i + 1] == 1)
58 cout << " ";
59 else
60 cout << endl;
61 }
62 }
63
64 void bianli(Tu &shuzu, int v, int visit[], int &b, int &max, int x)//遍历图
65 {
66 visit[v] = 1;
67
68 max += shuzu.dian[v];
69 if (max >= b)
70 b = max;
71
72 int a = 0, bo = 0;
73 for (int w = 1; w <= shuzu.diannum; w++)
74 {
75 for (int c = 1; c <= shuzu.diannum; c++)
76 {
77 if ((visit[w] == 0) && (shuzu.xian[c][w] == 1) && (visit[c] == 1))
78 {
79 a = w;
80 bo = 1;
81 break;
82 }
83 }
84 if (bo == 1)
85 {
86 break;
87 }
88 }
89 for (int w = 1; w <= shuzu.diannum; w++)
90 {
91 for (int c = 1; c <= shuzu.diannum; c++)
92 {
93 if ((visit[w] == 0) && (shuzu.xian[c][w] == 1) && (visit[c] == 1))
94 {
95 if (shuzu.dian[a]<shuzu.dian[w])
96 {
97 a = w;
98 }
99 }
100 }
101 }
102 if (b + shuzu.dian[a]<0)
103 {
104 shuzu.xian[v][a] = 0;
105 }
106 else
107 {
108 bianli(shuzu, a, visit, b, max, x);
109 }
110 }
111
112 int NoVisit(int visit[], Tu shuzu)
113 {
114 int k = 0, i;
115 for (i = 1; i <= shuzu.diannum; i++)
116 {
117 if (visit[i] == 0)
118 {
119 k = i;
120 break;
121 }
122 }
123 return k;
124 }//判断图中没有visit的项
125
126 int main()
127 {
128 Tu shuzu;
129 int x, y;
130 int i;
131
132 fstream infile("input.txt", ios::in); //打开指定文件
133 if (!infile)
134 {
135 cout << "open error!" << endl;
136 exit(1);
137 }
138 infile >> x >> y; //从文件中读取数组行数和列数
139 for (i = 1; i <= x*y; i++)
140 {
141 infile >> shuzu.dian[i];
142 }
143 infile.close();
144 set(shuzu, x, y);
145 cout << "数组为:" << endl;
146 output(shuzu);
147
148 int v = 1, b[N] = { 0 }, h = 0;
149
150 for (i = 1; i <= shuzu.diannum; i++)
151 {
152 if (shuzu.dian[i]<0)
153 {
154 b[i] = shuzu.dian[i];
155 }
156 else
157 {
158 int visit[N] = { 0 };
159 int max = 0;
160 bianli(shuzu, i, visit, b[i], max, x);
161 }
162 }
163
164 int max = b[1];
165 for (int i = 2; i <= shuzu.diannum; i++)
166 {
167 if (b[i]>max)
168 max = b[i];
169 }
170 cout << "最大联通子数组的和为:" << max << endl;
171
172 return 0;
173 }