二维

修改快排算法,让其按照二维数组的第二个值的大小排序

微笑、不失礼 提交于 2019-11-29 12:29:28
用途:贪心算法的按结束事件早的排序。 代码: int a [ 5 ] [ 2 ] ; void sort ( int left , int right ) { //a[i][j] 对i个进行排序,按照a【x】的第一个 (最早结束) if ( left >= right ) return ; int i = left ; int j = right ; int key = a [ left ] [ 1 ] ; int key0 = a [ left ] [ 0 ] ; while ( i < j ) { while ( i < j && key <= a [ j ] [ 1 ] ) j -- ; a [ i ] [ 0 ] = a [ j ] [ 0 ] ; a [ i ] [ 1 ] = a [ j ] [ 1 ] ; while ( i < j && key >= a [ i ] [ 1 ] ) i ++ ; a [ j ] [ 0 ] = a [ i ] [ 0 ] ; a [ j ] [ 1 ] = a [ i ] [ 1 ] ; } a [ i ] [ 1 ] = key ; a [ i ] [ 0 ] = key0 ; sort ( left , i - 1 ) ; sort ( i + 1 , right ) ; } 来源: CSDN 作者: 没实力真痛苦 链接:

二维差分与二维前缀和

亡梦爱人 提交于 2019-11-29 12:26:20
推荐模板题: [USACO19FEB]Painting The Barn 差分与前缀和互为逆运算,即差分数组的前缀和数组为原数组,前缀和数组的差分数组为原数组.二者都利用了容斥原理,这一点在二维平面(或者二维数组)中体现的更加明显. 那么我们先来讲二维前缀和 二维前缀和 一维的前缀和数组是求从数组的首项加到当前项的和,即: \[ sum[i]=\sum_{j=1}^{i}a[j]=(\sum_{j=1}^{i-1}a[j])+a[i]=sum[i-1]+a[i] \] 这就是一维前缀和的递推方法. 那么二维的前缀和,我们定义为以二维数组的首行首列(即左上角)元素为左上角,当前位置元素为右下角的矩阵的元素和.当我们推到 \((i,j)\) 时,我们考虑该怎么计算 \(sum[i][j]\) .由于左上角已经固定,我们只考虑右下角.当右下角为 \((i,j-1)\) 时,这是一个 \((i,j)\) 左侧的矩阵,当右下角为 \((i-1,j)\) 时,这表示一个 \((i,j)\) 上方的矩阵.那么如果我们要求 \((i,j)\) 左上方所有元素的和,是不是只要将这两个已经计算好的矩阵和加起来,再加上 \(a[i][j]\) 就行了呢? 当然不是. 因为左侧的矩阵和上方的矩阵有一个重合部分,即一个以 \((i-1,j-1)\) 为右下角的,完全位于 \((i,j)\) 左上方的矩阵

P3335(蚂蚁寻路 二维dp呜呜呜)

独自空忆成欢 提交于 2019-11-29 06:54:12
题目 一定会保证走出的路线是好几个底在一个水平线高低可能不同的矩形紧挨着。 然后总共有2*k+1个矩阵 第奇数个矩阵比旁边的矩阵高。 剩下的就是二维DP f[i][j][k][h]:以第i行第j列为右下角而且这是选的第k个矩阵 高度为h 的权值和最大是多少? 1.第i行(定量):第j列与第j-1列是同一个矩形 f[i][j][k][h]=f[i][j-1][k][h]+s[j][i]-s[j][h-1]; 2.第i行(定量): 1*.k为奇数:(应该由第k-1个矩形走向k是往高处走的) f[i][j][k][h]=f[i][j-1][k-1][h*]+s[j][i]-s[j][h-1];(h*<h) 2*.k为偶数:(应该由第k-1个矩形走向k是往低处走的) f[i][j][k][h]=f[i][j-1][k-1][h*]+s[j][i]-s[j][h-1];(h*>h) 由于第2种情况每次枚举最大的f[i][j-1][k][h*]很慢.所以我们依靠另一个数组g[i][j][k][h][0/1]; g[i][j][k][h][0/1]:以第i行第j列为右下角而且这是选的第k个矩阵 高度小于h/大于h 的f[i][j][k][h]的最大和. # include <bits/stdc++.h> using namespace std ; const int N = 100 + 5 ,

threejs点击事件

醉酒当歌 提交于 2019-11-29 06:37:06
本文链接:https://blog.csdn.net/ithanmang/article/details/80897888 示例浏览地址:https://ithanmang.gitee.io/threejs/home/201807/20180703/02-raycasterDemo.html 双击鼠标左键选中模型并显示信息。 首先,解释一下三种坐标系的概念:场景坐标系(世界坐标系)、屏幕坐标系、视点坐标系。 场景坐标 通过three.js构建出来的场景,都具有一个固定不变的坐标系(无论相机的位置在哪),并且放置的任何物体都要以这个坐标系来确定自己的位置,也就是(0,0, 0)坐标。例如我们创建一个场景并添加箭头辅助。 屏幕坐标 在显示屏上的坐标就是屏幕坐标系。 如下图所示,其中的clientX和clientY的最值由,window.innerWidth,window.innerHeight决定。 视点坐标 视点坐标系就是以相机的中心点为原点,但是相机的位置,也是根据世界坐标系来偏移的,webGL会将世界坐标先变换到视点坐标,然后进行裁剪,只有在视线范围(视见体)之内的场景才会进入下一阶段的计算 如下图添加了相机辅助线. 射线检测 若想获取鼠标点击的物体,name就需要把屏幕坐标系转换为three.js中的三维坐标系。 three.js提供了一个类THREE

二维最长上升子序列

血红的双手。 提交于 2019-11-29 05:02:43
1、二维最长上升子序列 —— 相等可嵌套 (1)排序,一维正排序,二维正排序; (2)对第二维度,求 最长 弱上升子序列,upper_bound #include <iostream> #include <vector> #include <algorithm> //sort、max using namespace std; bool cmp(vector<int> &num1, vector<int> &num2) { if (num1[0] != num2[0]) return num1[0] < num2[0]; // 一维正排 else return num1[1] < num2[1]; // 弱上升,二维正排 } /* 输入 5 2 2 2 4 3 3 2 5 4 5 输出 4 输入 2 2 2 3 2 输出 2 */ int main() { int n; cin >> n; if (n <= 1) { cout << n; return 0; } //上升排序 vector<vector<int>> num(n, vector<int>(2)); for (int i = 0; i < n; i++) { cin >> num[i][0] >> num[i][1]; } sort(num.begin(), num.end(), cmp); // //二分查找,N

C++ 指针与二维(多维)数组

假装没事ソ 提交于 2019-11-29 01:46:45
在 上一章 中, 介绍了指针与一维数组的联系 (指针数组叫 动态数组 ) 一维数组搞定了, 二维数组 ? 能否 按照一维数组的思路 ?------可以 例: #include <iostream> using namespace std; int main() { int num[3][3]; for(int i=0;i<3;i++) for(int j=0;j<3;j++) cin>>num[i][j]; for(int i=0;i<3;i++) { for(int j=0;j<3;j++) cout<<num[i][j]<<' '; cout<<endl; } return 0; } 其内存状态如下, 看不懂看 这里 : 现在问题是, 出现了3个指针, 如何将其融合于一个指针之中呢? 其实上想一想就知道, 就是双重指针 ( ** ) 好, 现在我们已经有了一个申请 列 的空间的雏形: #include <iostream> using namespace std; int main() { int **num=new int*[3];//申请3个指针空间(给列用, 3个列) return 0; } 现在内存状态如下: 现在问题又来了: 如何 申请行的空间 ? 这也不难, 想一下, num[0], num[1], num[2] 都是指针, 而指针怎么再开辟空间, 不是又回到了

数据结构——稀疏数组与二维数组

这一生的挚爱 提交于 2019-11-28 21:40:56
title: 稀疏数组与二维数组 categories: 数据结构 tags: 数据结构 typora-root-url: …/ abbrlink: 1245787517 date: 2019-09-20 16:40:15 稀疏数组 介绍 当一个数组中大部分元素为0,或者为同一个值的数组时,可以使用稀疏数组来保存该数组。 处理方式 记录数组一共有几行几列,有多少个不同的值 把具有不同值的元素的行列及值记录在一个小规模的数组中,从而缩小程序的规模 图示 {% asset_img 1569747096169.png %} package com . leeyf . sparsearray ; import java . io . * ; /** * 稀疏数组 */ public class SparseArray { public static void main ( String [ ] args ) { /* * 将二维数组转换成稀疏数组 */ //创建原始的二维数组(五子棋盘) //0 表示没有值 1表示黑子 2表示蓝子 int [ ] [ ] chessArr1 = new int [ 11 ] [ 11 ] ; chessArr1 [ 1 ] [ 2 ] = 1 ; chessArr1 [ 2 ] [ 3 ] = 2 ; chessArr1 [ 5 ] [ 6 ] = 2 ;

#(二维DP模型)洛谷P1387 最大正方形(普及/提高-)

拈花ヽ惹草 提交于 2019-11-28 14:48:02
题目描述 在一个n*m的只包含0和1的矩阵里找出一个不包含0的最大正方形,输出边长。 输入格式 输入文件第一行为两个整数n,m(1<=n,m<=100),接下来n行,每行m个数字,用空格隔开,0或1. 输出格式 一个整数,最大正方形的边长 输入输出样例 输入 #1 复制 4 4 0 1 1 1 1 1 1 0 0 1 1 0 1 1 0 1 输出 #1 复制 2分析:1.因为给出的数据以图的形式,那么很显然,为了维护每个点的状态,dp数组必须设成二维状态以表示坐标。2.设f[i][j]表示以(i,j)为右下角所构成的最大正方形,用a[i][j]存储图。3.推状态转移方程:如a[i][j]:       那么有对应的f[i][j]:  0 1 1 1            0 1 1 1    1 1 1 0            1 1 2 0   0 1 1 0            0 1 2 0   1 1 0 1            1 1 2 1 得出if(a[i][j]==1)  f[i][j]=min(f[i-1][j-1],min(f[i][j-1],f[i-1][j]))+1;(经验:遇到这样图的题,尝试设出状态后,因为图十分直观,可以先手动模拟几个答案,从而直接看出转移方程)代码如下: #include<iostream> using namespace

二维状压DP经典题

拈花ヽ惹草 提交于 2019-11-28 13:53:19
炮兵阵地 题目链接 题目大意:在n*m的地图上放置炮兵,每个炮兵的攻击范围是上下左右两格内,有两种不同的地形,山地(用“H” 表示),平原(用“P”表示),只有平原可以布置炮兵,在不冲突的前提下最多可以布置多少炮兵? 这道题非常经典,我们用dp[i] [j] [k]表示第i行在第j种选取状态下,第i-1行在第k种选取状态下前i行最多摆放的炮兵数量。然后我们首先 预处理每一行所有的合法状态 ,以降低时间复杂度。用num[i]表示第i行的合法状态数量,state[i] [j]表示第i行的第j种合法状态是什么,用temp[i]存储第i行的初始状态,用c[i]存储每种合法状态对应的炮兵数量。 可以不处理直接枚举所有状态吗 如果不预先处理合法状态,那么每一行所有的状态可能有2^10 = 1024种,由于炮兵的摆放需要考虑前两行的状态,那么三个循环枚举状态就会达到惊人的时间复杂度,所以预处理很关键!进行预处理我们会发现每一行的合法状态最多60种,这样即使是3个循环复杂度也会很低。 其他细节都在代码里了。 #include <bits/stdc++.h> using namespace std; int n,m,ans; int dp[105][65][65]; int num[105],temp[105]; int state[105][65]; int c[1 << 10 + 5]; int

hdoj 1715 大菲波数

只愿长相守 提交于 2019-11-28 10:55:23
一开始以为简单的通过递推就可以了,但后面发现wa了,查了一下,也才注意到题目很明显的说了大数,所以什么类型都不够用,位数很大。 查了一下,了解到可以用二维数组做,即第一维是控制算到第几个的,第二维用来控制所得数的位数,类似于用手动的方法来计算数列; 代码如下: #include <stdio.h> #include <string.h> int a[1005][1005]; int main() { int T; scanf("%d", &T); while (T--) { int n; scanf("%d", &n); int c; int d = 0;//用来控制位数,并且输出时知道从何输出,此题手动进行运算,每一位数字存在每一个二维数组中,第一维用来控制算得的数,而第二维才是用来存数 memset(a, 0, sizeof(a)); a[1][0] = 1;a[2][0] = 1;//第一个和第二个数要先保存下来 for (int i = 3;i <= n;i++)//从第三个数开始都是等于前两个数的和 { c = 0;//保存余数 for (int j = 0;j <= d;j++) { a[i][j] = a[i - 1][j] + a[i - 2][j] + c;//计算结果 c = a[i][j] / 10;//将其他的数进位 a[i][j] %= 10;/