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 ...
随机推荐
- Exceeded maximum number of retries. Exceeded max scheduling attempts 3 for instance 7d90eb80-29e2-4238-b658-ade407ff9456. Last exception: [u'Traceback (most recent call last):\n', u' File "/usr/lib/py
Exceeded maximum number of retries. Exceeded max scheduling attempts 3 for instance 7d90eb80-29e2-42 ...
- SQLServer 窗口函数
一.窗口函数的作用 窗口函数是对一组值进行操作,不需要使用GROUP BY 子句对数据进行分组,还能够在同一行中同时返回基础行的列和聚合列.窗口函数,基础列和聚合列的查询都非常简单. 二.语法格式 窗 ...
- sql case when 多条件
when 'ChangeProductName'= case --联名借姓名 --when a.ChangeProductName is not null then (substr ...
- PHP:PHP页面编码问题(转载)
MySQL数据库编码.html页面编码.PHP或html文件本身编码要全部一致. 1.MySQL数据库编码:建立数据库时指定编码(如gbk_chinese_ci),建立数据表.建立字段.插入数据时不要 ...
- Loadrunner:集合点(Rendezvous)
集合点:等到特定的用户数后再一起执行某个操作,比如一起登录.一起发信,一般情况下使用不到集合点,不过,订票系统或者促销类需要用到,比如说某个促销品的促销时间在8点到8点30,这样的话,就可能出现在8点 ...
- 条款22 template method 模式
template method 模式,模板方法模式 其实他和C++模板没有关系. 前者是提供的为派生类设计者提供清晰指示的一种方法,这个事实表示"如何去实现基类所规定的契约" 基类 ...
- activiti搭建(五)BPMN介绍
转载请注明源地址:http://www.cnblogs.com/lighten/p/5931207.html 对于BPMN我也不是十分清楚,目前也只是因为对于Modeler中不熟悉的组件查询,来对这部 ...
- CSS 3 中二维三维以及渐变过程简单总结 及效果(动图不好发)
一. 不动,区域内的变化(本质生产一张图片) /*渐变 1 长方形之渐变先定义长方形的宽高大小(好观察最好加边框) ...
- CSS3新增伪类
p:last-of-type 选择其父元素的最后的一个P元素 p:last-child 选择其父元素的最后子元素(一定是P才行) p:first-of-type ...
- Visual Studio 2010 更新NuGet Package Manager出错解决办法
在Visual Studio 2010的扩展管理器中发现NuGet Package Manger有最新版本更新提示,选择更新安装提示以下错误信息: 2013/4/25 1:11:48 - Micros ...