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 ...
随机推荐
- StackExchange.Redis使用和封装小试
StackExchange.Redis使用和封装小试 https://git.oschina.net/Ultralisk/ThorActor/blob/ThorActor/DBUtility/Redi ...
- Visual studio 2013 Team Foundation Server TFS2013 设置签出独占锁
摘自: http://www.cnblogs.com/52XF/p/4239056.html 以备自查 如侵权,请告知
- A planning attack on a commuter train carriage in Taipei
Last night an explosion on a commuter train carriage in Taipei Songshan railway station wounded at l ...
- leetcode 118
118. Pascal's Triangle Given numRows, generate the first numRows of Pascal's triangle. For example, ...
- SQLserver2012 修改数据库架构
还原数据库以后,发现有一张表的架构不对,执行sql提示:对象名无效.
- 网络基础知识、ASP.NET 核心知识(1)*
为什么要写网络? 我原本的计划是这样的,连续两天梳理ASP.NET开发的核心知识.说到这呢,有人问了.“不是说好了做ASP.NET笔记吗?为啥要写网络基础知识?是不是傻?” 原因是这样的.作为网站开发 ...
- [视频]ARM告诉你物联网怎么玩,mbed 6LoWPan demo
该视频演示了基于arm mbed的物联网设备间的6LoWPAN应用,如连接家里的土壤湿度传感器,灯光控制,安防联动等应用. 演示视频 原创文章,转载请注明: 转载自 http://www. ...
- xode View 的封装
1.Xcode自带头文件的路径 /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Develo ...
- 用,隔开sql临时表
IF OBJECT_ID('[kkd].[proc_kkd_GetAutoExamineBid]') IS NOT NULL BEGIN DROP PROC [kkd].[proc_kkd_GetAu ...
- (转)Java操作Hbase进行建表、删表以及对数据进行增删改查,条件查询
1.搭建环境 新建JAVA项目,添加的包有: 有关Hadoop的hadoop-core-0.20.204.0.jar 有关Hbase的hbase-0.90.4.jar.hbase-0.90.4-tes ...