homework-02 二维的,好喝的(二维数组的各种子数组)
1)输入部分
对于输入部分,我定义的输入格式是这样的
前两行为列数和行数

如果文件无法打开,或者输入文件格式不对,均会提示出错并退出
2)二维数组的最大矩形子数组
首先,我使用最最简单的暴力算法,直接用四个for循环实现,这个算法虽然时间复杂度达到O(M^2*N^2),但可以用于检测优化算法的正确性。
int maxNum1(int m,int n){
int pre[][] = {};
int sum = ,max = ;
for(int i=;i<=m;i++)
for(int j=;j<=n;j++)
pre[i][j]=pre[i-][j]+pre[i][j-]-pre[i-][j-]+matrix[i][j];
for(int i=; i<=m; i++)
for(int j=;j<=n;j++)
for(int k=i; k<=m; k++)
for(int l=j; l<=n; l++){
sum = pre[k][l] - pre[k][j-] - pre[i-][l] + pre[i-][j-];
if(sum > max)
max = sum;
}
return max;
}
matrix是存放输入的二维数组,从[1][1]开始
pre[i][j]=pre[i-1][j]+pre[i][j-1]-pre[i-1][j-1]+matrix[i][j];
是将pre[i][j]存放从matrix[1][1]到matrix[i][j]这个的矩形数组和
故在后面可以用
sum = pre[k][l] - pre[k][j-1] - pre[i-1][l] + pre[i-1][j-1];

一维的情况,上次已经给出了O(N)的算法,是否可以在二维也用上呢?
我是将一个维度上使用暴搜,另一个维度上为上次作业给出的O(N)的算法
int maxNum2(int m,int n){
int pre[][] = {};
int sum = ,max = ;
int columnsMax = ;
for(int i=;i<=m;i++)
for(int j=;j<=n;j++)
pre[i][j] = pre[i][j-] + matrix[i][j];
for(int i=; i<=n; i++)
for(int j=i;j<=n;j++){
for(int k=; k<=m; k++){
if(sum<)
sum=pre[k][j] - pre[k][i-];
else
sum+=pre[k][j] - pre[k][i-];
if(columnsMax < sum)
columnsMax = sum;
}
sum = ;
}
return columnsMax;
}
这次的处理和上一个不一样,由于在一个维度上用了那个O(N)算法,所以pre[i][j]存的是i行 matrix[i][1]到matrix[i][j]的和
这样算法的时间复杂度为O(M*N^2)
其实,还可以优化一点,就是选择使用O(N)算法的维度时选择M,N中大者,则时间复杂度可以降到O(M*N*min(M,N))
3)水平,垂直!
这个改动,我想了想,水平的话就是水平方向在放一个同样的数组,然后继续用2)中算法
垂直也一样的
| 2 | -1 | 3 |
| -1 | 1 | -2 |
变为
| 2 | -1 | 3 | 2 | -1 | 3 |
| -1 | 1 | -2 | -1 | 1 | -2 |
这样的话,就容易了
int maxNum4(int m, int n){
int pre[][] = {};
int sum = ,max = ;
int columnsMax = ;
for(int i=;i<=m;i++)
for(int j=;j<=*n;j++)
pre[i][j] = pre[i][j-] + matrix[i][(j-)%n +];
for(int i=; i<=n; i++)
for(int j=i;j<=i+n-;j++){
for(int k=; k<=m; k++){
if(sum<)
sum=pre[k][j] - pre[k][i-];
else
sum+=pre[k][j] - pre[k][i-];
if(columnsMax < sum)
columnsMax = sum;
}
sum = ;
}
return columnsMax;
}
算法上有些小改动,就是要限制子数组行列不超过原数组
垂直的就不在这写了。
4)轮胎?备胎~
这个我是这样想的,就是将4个原数组拼接一个大数组,然后继续用前面的算法
| 1 | -1 |
| -1 | 2 |
变为
| 1 | -1 | 1 | -1 |
| -1 | 2 | -1 | 2 |
| 1 | -1 | 1 | -1 |
| -1 | 2 | -1 | 2 |
在实现上和上面的水平代码大同小异。
5)连通!真的想不出来了
首先想到贪心,二维贪心好像不可行
接着想用图论,把矩阵转为一个有向图,求出一条最大连通路径

使用了各种最短路径算法,还是不行
真心难啊。放弃治疗!
附:代码)
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h> #define FIE "Input string was not in a correct format"
FILE* in;
int matrix[][] = {};
int map[][] = {};
int sxbkM[][] = {-}; void positiveSub(int m, int n, int label );
inline void error(char* s){
printf("Error: ");
printf("%s\n",s);
exit();
}
int maxNum1(int m,int n){
int pre[][] = {};
int sum = ,max = ;
for(int i=;i<=m;i++)
for(int j=;j<=n;j++)
pre[i][j]=pre[i-][j]+pre[i][j-]-pre[i-][j-]+matrix[i][j]; for(int i=; i<=m; i++)
for(int j=;j<=n;j++)
for(int k=i; k<=m; k++)
for(int l=j; l<=n; l++){
sum = pre[k][l] - pre[k][j-] - pre[i-][l] + pre[i-][j-];
if(sum > max)
max = sum;
}
return max;
}
int maxNum2(int m,int n){
int pre[][] = {};
int sum = ,max = ;
int columnsMax = ;
for(int i=;i<=m;i++)
for(int j=;j<=n;j++)
pre[i][j] = pre[i][j-] + matrix[i][j]; for(int i=; i<=n; i++)
for(int j=i;j<=n;j++){
for(int k=; k<=m; k++){
if(sum<)
sum=pre[k][j] - pre[k][i-];
else
sum+=pre[k][j] - pre[k][i-];
if(columnsMax < sum)
columnsMax = sum;
}
sum = ;
} return columnsMax;
}
//水平
int maxNum4(int m, int n){
int pre[][] = {};
int sum = ,max = ;
int columnsMax = ;
for(int i=;i<=m;i++)
for(int j=;j<=*n;j++)
pre[i][j] = pre[i][j-] + matrix[i][(j-)%n +]; for(int i=; i<=n; i++)
for(int j=i;j<=i+n-;j++){
for(int k=; k<=m; k++){
if(sum<)
sum=pre[k][j] - pre[k][i-];
else
sum+=pre[k][j] - pre[k][i-];
if(columnsMax < sum)
columnsMax = sum;
}
sum = ;
} return columnsMax;
} //竖直环
int maxNum5(int m,int n){
int pre[][] = {};
int sum = ,max = ;
int columnsMax = ;
for(int i=;i<=m;i++)
for(int j=;j<=n;j++)
pre[i][j] = pre[i][j-] + matrix[i][j]; int x=;
for(int i=; i<=n; i++)
for(int j=i;j<=n;j++){
for(int k=; k <= m*; k++){
if(sum< || x >m){
x=;
sum=pre[(k-)%m + ][j] - pre[(k-)%m + ][i-];
}
else{
x++;
sum+=pre[(k-)%m + ][j] - pre[(k-)%m + ][i-];
}
if(columnsMax < sum)
columnsMax = sum;
}
sum = ;
} return columnsMax;
}
//备胎
int maxNum6(int m, int n){
int pre[][] = {};
int sum = ;
int columnsMax = ;
for(int i=;i<=m;i++)
for(int j=;j<=*n;j++)
pre[i][j] = pre[i][j-] + matrix[i][(j-)%n +]; int x=;
for(int i=; i<=n; i++)
for(int j=i;j<=i+n-;j++){
for(int k=; k <= m*; k++){
if(sum< || x >m){
x=;
sum=pre[(k-)%m + ][j] - pre[(k-)%m + ][i-];
}
else{
x++;
sum+=pre[(k-)%m + ][j] - pre[(k-)%m + ][i-];
}
if(columnsMax < sum)
columnsMax = sum;
}
sum = ;
} return columnsMax; } int getNum(){
char num[],input;
int i=,n;
input = fgetc(in);
while(!isdigit(input) && input != '-' ){
if(input != ' ' && input != '\n' &&
input != NULL && input != ',' &&
input != '\0')
error(FIE);
input = fgetc(in);
} do{
num[i++] = input;
input = fgetc(in);
}while(isdigit(input)); num[i] = '\0';
n = atoi(num); return n;
}
void initialize(int m,int n){
for(int i=; i<; i++)
for(int j=; j<; j++)
sxbkM[i][j] = -;
for(int i=; i<=m; i++){
for(int j=; j<=n; j++){
matrix[i][j] = getNum();
}
}
}
int maxNum3(int m, int n){
return ;
}
void positiveSub(int i, int j, int label ){
map[i][j] = label;
if(matrix[i][j+] >= && map[i][j+] ==)
positiveSub(i,j+,label); if(matrix[i+][j] >= && map[i+][j] ==)
positiveSub(i+,j,label); if(matrix[i][j-] >= && map[i][j-] ==)
positiveSub(i,j-,label); if(matrix[i-][j] >= && map[i-][j] ==)
positiveSub(i-,j,label);
} int main(int argc, char *argv[]){ int m,n;
char input,num[];
if( argc == )
error("Plese run with the file name");
else if(argc == ){
if((in = fopen(argv[], "r")) == NULL)
error("File can not open");
}
else if(argc == ){
if((in = fopen(argv[], "r")) == NULL)
error("File can not open");
}
else if(argc == ){
if((in = fopen(argv[], "r")) == NULL)
error("File can not open");
}
else error("Too many parameters"); m = getNum();
if(fgetc(in)!= '\n')
error(FIE);
n = getNum();
if(fgetc(in)!= '\n')
error(FIE);
initialize(m,n); if( argc == )
std::cout<<std::endl<<"子数组: "<< maxNum2(m,n);
else if( argc == ){
if(strcmp(argv[],"/a") == )
printf("Sorry,I haven't solved the problem.\n");
else if(strcmp(argv[],"/h") == )
std::cout<<std::endl<<"水平环: "<< maxNum4(m,n);
else if(strcmp(argv[],"/v") == )
std::cout<<std::endl<<"竖直环: "<< maxNum5(m,n);
else error("Wrong parameter");
}
else{
if((strcmp(argv[],"/v") == && strcmp(argv[],"/h") == )
||(strcmp(argv[],"/h") == && strcmp(argv[],"/v") == ) )
std::cout<<std::endl<<"备胎环: "<< maxNum6(m,n);
else error("Wrong parameter\n");
}
return ;
}
homework-02 二维的,好喝的(二维数组的各种子数组)的更多相关文章
- Android zxing 解析二维码,生成二维码极简demo
zxing 官方的代码很多,看起来很费劲,此demo只抽取了有用的部分,实现了相机预览解码,解析本地二维码,生成二维码三个功能. 简化后的结构如下: 废话少说直接上代码: BaseDecodeHand ...
- Android实例-实现扫描二维码并生成二维码(XE8+小米5)
相关资料: 第三方资料太大没法写在博文上,请下载CSDN的程序包. 程序包下载: http://download.csdn.net/detail/zhujianqiangqq/9657186 注意事项 ...
- C# ZXing.Net生成二维码、识别二维码、生成带Logo的二维码(二)
1.使用ZXint.Net生成带logo的二维码 /// <summary> /// 生成带Logo的二维码 /// </summary> /// <param name ...
- C语言数组:C语言数组定义、二维数组、动态数组、字符串数组
1.C语言数组的概念 在<更加优美的C语言输出>一节中我们举了一个例子,是输出一个 4×4 的整数矩阵,代码如下: #include <stdio.h> #include &l ...
- 求二维数组的最大子数组———曹玉松&&蔡迎盈
继上节课老师让求了一维数组最大的子数组后,这节课堂上,老师加深了难度,给了一个二维数组,求最大子数组,开始觉得很容易,但是自己思考起来感觉这个算法很困难,既需要考虑数组直接的连续,又要求出最大的,老师 ...
- 二维数组转化为一维数组 contact 与apply 的结合
将多维数组(尤其是二维数组)转化为一维数组是业务开发中的常用逻辑,除了使用朴素的循环转换以外,我们还可以利用Javascript的语言特性实现更为简洁优雅的转换.本文将从朴素的循环转换开始,逐一介绍三 ...
- 二维数组 cudaMallocPitch() 和三维数组 cudaMalloc3D() 的使用
▶ 使用函数 cudaMallocPitch() 和配套的函数 cudaMemcpy2D() 来使用二维数组.C 中二维数组内存分配是转化为一维数组,连贯紧凑,每次访问数组中的元素都必须从数组首元素开 ...
- 二维数组,锯齿数组和集合 C# 一维数组、二维数组(矩形数组)、交错数组(锯齿数组)的使用 C# 数组、多维数组(矩形数组)、锯齿数组(交叉数组)
二维数组,锯齿数组和集合 一.二维数组 二维数组:一维数组----豆角二维数组----表格 定义:1.一维数组:数据类型[] 数组变量名 = new 数据类型[数组长度];数据类型[] 数组变量名 = ...
- PCA 实例演示二维数据降成1维
import numpy as np # 将二维数据降成1维 num = [(2.5, 2.4), (0.5, 0.7), (2.2, 2.9), (1.9, 2.2), (3.1, 3.0), (2 ...
随机推荐
- PAT1013. Battle Over Cities(邻接矩阵、邻接表分别dfs)
//采用不同的图存储结构结构邻接矩阵.邻接表分别dfs,我想我是寂寞了吧,应该试试并查集,看见可以用并查集的就用dfs,bfs代替......怕了并查集了 //邻接矩阵dfs #include< ...
- Dynamic AX 4.0 用户组权限SecurityKey
UserId _userId = "IT001"; UserGroupId _userGroupId = "ABC_1"; DomainId _domainId ...
- 有没有好用的开源sql语法分析器? - 匿名用户的回答 - 知乎
有没有好用的开源sql语法分析器? - 匿名用户的回答 - 知乎 presto,hive,drill,calcite,sparksq
- C# 发送邮件方法2
一. 发送邮件程序:(使用System.Web.Mail下的类) "; //SMTP服务密码 strFrom = "jailu@163.com"; //发送方邮件地址 C ...
- Java 单测 回滚
Java 在单测的时候 需要做回滚 设置如下: 需要添加以下 注解 在类上 defaultRollback = true : 为 默认全部回滚 defaultRollback = false : 为 ...
- 设计模式-适配器模式(Adapter)
简介: 适配器模式在我看来是最无聊的一种模式,因为他根本不是一种新的创意模式,而是一种不得已而为之的模式.就算不学适配器模式,在具体应用场景中也会自然而然的想到这种解决方案. 张三在英国留学时买了个笔 ...
- SQL多表查询:内连接、外连接(左连接、右连接)、全连接、交叉连接
aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAPgAAADCCAIAAADrUpiXAAAGYklEQVR4nO3dQXqjuAJFYa1LC9J6tB
- Data Being Added Conflicts with Existing Data
While developing a page with multiple scrolls levels, and especially when using a grid, you may get ...
- mysql 5.7压缩包安装笔记
转载请注明出处http://www.cnblogs.com/havedream/p/5075263.html 重装系统之后准备安装mysql,看到官网上有mysql 5.7.10可以下载就点了,然后就 ...
- Winform主窗体的设置
软件必然涉及到一个主窗体MainForm,下面介绍一下几个简单的属性设置,可能比较有用 (1)icon,当然是咱们软件的图标了,设置上去即可 (2)isMdiContainer,这个比较重要了哦,必须 ...