指针

乘积最大,双指针+贪心

流过昼夜 提交于 2020-02-29 14:22:00
给定 N 个整数 A1,A2,…AN 。 请你从中选出 K 个数,使其乘积最大。 请你求出最大的乘积,由于乘积可能超出整型范围,你只需输出乘积除以 1000000009 的余数。 注意,如果 X<0 , 我们定义 X 除以 1000000009 的余数是负(−X)除以 1000000009 的余数,即:0−((0−x)%1000000009) 输入格式 第一行包含两个整数 N 和 K 。 以下 N 行每行一个整数 Ai 。 输出格式 输出一个整数,表示答案。 数据范围 1≤K≤N≤105 , −105≤Ai≤105 输入样例1: 5 3 -100000 -10000 2 100000 10000 输出样例1: 999100009 输入样例2: 5 3 -100000 -100000 -2 -100000 -100000 输出样例2: -999999829 思路:枚举k和n的关系 如果相等,那自然要全取,如果k<n,当k是偶数的时候,答案一定大于零,证明:如果n中有奇数个负数,一定存在答案可以大于0,如果有偶数个负数,也一样。如果k为奇数,那就可以划分成k-1和1,如果最大值都小于0,那肯定小于0,最大值大于0,那么一定大于0. #include<bits/stdc++.h> using namespace std ; typedef long long ll ; const int

衣带渐宽终不悔,为“指针”消得人憔悴(四)

旧城冷巷雨未停 提交于 2020-02-29 12:22:32
至臻篇—— void 类型指针 void  =>  空类型 void*  =>  空类型指针,只存储地址的值,丢失类型,无法访问,要访问其值,           我们必须对这个指针做出正确的类型转换,然后再间接引用指针。 所有其它类型的指针都可以隐式自动转换成 void 类型指针,反之需要强制转换 # include <stdio.h> # include <stdlib.h> int main ( void ) { int arr [ ] = { 1 , 2 , 3 , 4 , 5 } ; char ch = 'a' ; void * p = arr ; //定义了一个void 类型的指针 //p++; //不可以, void * 指针不允许进行算术运算 p = & ch ; //其它类型可以自动转换成void * 指针 //printf("数组第一个元素: %d\n", *p); //不可以进行访问 printf ( "p: 0x%p ch: 0x%p\n" , p , & ch ) ; //强制类型转化 char * p1 = ( char * ) p ; printf ( "p1 指向的字符是: %c\n" , * p1 ) ; system ( "pause" ) ; return 0 ; }      函数指针 # include <stdio.h> #

安卓强指针sp的作用和用法

一个人想着一个人 提交于 2020-02-29 09:42:26
在安卓中,很多地方都用到了android::sp<XXX>这种东西,sp其实是一个模板类,实现了强指针,在C++中,如果我们new了一个对象,但是如果在该对象已经没用的时候没有delete掉,那么该对象就会一直占用内存,导致内存泄露,比如下面的程序: class A { public: A() { printf("A::A()\n"); } void show() { printf("A::show()\n"); } ~A() { printf("A::~A()\n"); } int data; }; void test() { A *pA = new A; pA->show(); } int main() { test(); //dosomething... return 0; } 执行结果如下图所示,可以看到并没有调用~A()析构函数。 在函数test执行完后,由于没有delete pA,就会导致内存泄露,而安卓的sp可以解决这个问题,修改程序如下 class A : public RefBase { public: A() { printf("A::A()\n"); } void show() { printf("A::show()\n"); } ~A() { printf("A::~A()\n"); } int data; }; void test() { A *pA =

快慢指针

丶灬走出姿态 提交于 2020-02-29 09:23:45
所谓快慢指针中的快慢指的是指针向前移动的步长,每次移动的步长较大即为快,步长较小即为慢,常用的快慢指针一般是在单链表中让快指针每次向前移动2,慢指针则每次向前移动1。 快慢指针在提高查找性能方面的作用还是比较可观的,如以下应用: (1)如何快速找出未知长度单链表的中间节点? 普通方法:先遍历一遍单链表确定其长度L后,再从头节点出发循环L/2次即可查找到单链表的中间节点。该问题如果采用普通的方法虽然简单,但是查找效率太低。 快慢指针: 设置两个指针*fast、*slow都指向单链表的头节点,其中*fast的移动速度是*slow的2倍,当*fast指向末尾节点的时候,slow正好就在中间了,可以大大提高查找的效率。 当然,此时算法 还要考虑链表结点个数的奇偶数因素,当快指针移动x次后到达表尾(1+2x),说明链表有奇数个结点,直接返回慢指针指向的数据即可。如果快指针是倒数第二个结点,说明链表结点个数是偶数,这时 可以 实际情况 返回上中位数或下中位数或(上中位数+下中位数)的一半。 1 while (fast&&slow) 2 { 3   if (fast->next==NULL) 4    return slow ->data; 5   else if (fast->next!= NULL && fast->next->next== NULL) 6    return (slow -

走进C#,走进linq

假如想象 提交于 2020-02-29 09:04:02
过年在家,无所事事,拾起从没耐心看的C#入门,用三天的时间系统的翻了一遍(除了web)。又在代码上试了一把,有些心得,留于此处,以作纪念。 在C#中,没有指针,这让c++启蒙的我很不习惯。仔细研读,在C++中,有值类型和引用类型,其中的引用类型,就近似于c++中的指针。不过是不声明为指针。 写到这里,忽然泛起疑问,在不是传参的情形下,值类型如何表示为指针。仔细思索,如果不是为了传参,值类型有必要使用指针么。 想到这里,思索一下,c++中指针的用途:地址,数组,以及函数指针。 数组和函数指针在c#中都有。其中函数指针在c#中表现为委托。剩下的,就只有地址了。而c++中,用到数据地址的地方,不计数组,就是传参了。传参有引用类型ref标识。c#委员会(不知道是不是这个机构)想的果然很是周到 。 c#中,有一种类型叫作可空类型,就是使值类型的值也可为null,这种类型的标识方式是int? ,很是神奇。而有了这种类型,原本在设计中的很多工作都轻松了。想必你也有这种时候吧,n个成员变量,每个成员变量都要配一个bool类型的变量以标识这个变量是否启用。这是非常痛苦的事儿。而在c#里,引进了可空变量,于是问题轻松了。此外,??操作符的引入,进一步简化了代码。你知道??操作符么?这是一个二元操作符,如果第一个操作数非空,那就使用第一个操作数,如果第一个操作数为空,那就采用第二个操作数。没搞好着色插件

反汇编学习

让人想犯罪 __ 提交于 2020-02-29 07:06:48
(转: http://www.kuqin.com/assemble/20071122/2492.html ) 汇编语言和CPU以及内存,端口等硬件知识是连在一起的. 这也是为什么汇编语言没有通用性的原因. 下面简单讲讲基本知识(针对INTEL x86及其兼容机)   ============================   x86汇编语言的指令,其操作对象是CPU上的寄存器,系统内存,或者立即数. 有些指令表面上没有操作数, 或者看上去缺少操作数, 其实该指令有内定的操作对象, 比如push指令, 一定是对SS:ESP指定的内存操作, 而cdq的操作对象一定是eax / edx.    在汇编语言中,寄存器用名字来访问. CPU 寄存器有好几类, 分别有不同的用处:   1. 通用寄存器:   EAX,EBX,ECX,EDX,ESI,EDI,EBP,ESP(这个虽然通用,但很少被用做除了堆栈指针外的用途)      这些32位可以被用作多种用途,但每一个都有"专长". EAX 是"累加器"(accumulator), 它是很多加法乘法指令的缺省寄存器. EBX 是"基地址"(base)寄存器, 在内存寻址时存放基地址. ECX 是计数器(counter), 是重复(REP)前缀指令和LOOP指令的内定计数器. EDX是...(忘了..哈哈)但它总是被用来放整数除法产生的余数.

C语言指针的长度和类型

爱⌒轻易说出口 提交于 2020-02-29 06:27:00
本文地址: http://www.cnblogs.com/archimedes/p/point-length-type.html ,转载请注明源地址。 如果考虑应用程序的兼容性和可移植性,指针的长度就是一个问题,在大部分现代平台上,数据指针的长度通常是一样的,与指针类型无关,尽管C标准没有规定所有类型指针的长度相同,但是通常实际情况就是这样。但是函数指针长度可能与数据指针的长度不同。 指针的长度取决于使用的机器和编译器,例如:在现代windows上,指针是32位或是64位长 测试代码: #include<stdio.h> #include<math.h> #include<stdlib.h> #include<stddef.h> struct p{ int n; float f; }; int main() { struct p *sptr; printf("sizeof *char: %d\n", sizeof(char*)); printf("sizeof *int: %d\n", sizeof(int*)); printf("sizeof *float: %d\n", sizeof(float*)); printf("sizeof *double: %d\n", sizeof(double*)); printf("sizeof *struct: %d\n", sizeof

32位Intel CPU所含有的寄存器

拈花ヽ惹草 提交于 2020-02-29 06:16:52
4个数据寄存器(EAX、EBX、ECX和EDX) 2个变址和指针寄存器(ESI和EDI) 2个指针寄存器(ESP和EBP) 6个段寄存器(ES、CS、SS、DS、FS和GS) 1个指令指针寄存器(EIP) 1个标志寄存器(EFlags) 1、数据寄存器 数据寄存器主要用来保存操作数和运算结果等信息,从而节省读取操作数所需占用总线和访问存储器的时间。 32位CPU有4个32位的通用寄存器EAX、EBX、ECX和EDX。对低16位数据的存取,不会影响高16位的数据。这些 低16位寄存器分别命名为:AX、BX、CX和DX,它和先前的CPU中的寄存器相一致。 4个16位寄存器又可分割成8个独立的8位寄存器(AX:AH-AL、BX:BH-BL、CX:CH-CL、DX:DH-DL),每个寄 存器都有自己的名称,可独立存取。程序员可利用数据寄存器的这种“可分可合”的特性,灵活地处理字/字 节的信息。 寄存器AX和AL通常称为累加器(Accumulator),用累加器进行的操作可能需要更少时间。累加器可用于乘、 除、输入/输出等操作,它们的使用频率很高; 寄存器BX称为基地址寄存器(Base Register)。它可作为存储器指针来使用; 寄存器CX称为计数寄存器(Count Register)。在循环和字符串操作时,要用它来控制循环次数;在位操作 中,当移多位时,要用CL来指明移位的位数;

数据结构与算法分析:(五)循环链表

自闭症网瘾萝莉.ら 提交于 2020-02-29 02:05:50
一、前言 相信小伙伴们在前面两篇文章的详细介绍已经对单向链表、双向链表有一个很清晰的认识了。 数据结构与算法分析:(三)单向链表 数据结构与算法分析:(四)双向链表 接下来我们来介绍循环链表,你把单向链表、双向链表搞清楚了的话,循环链表自然也不难了。 循环链表可分为:单向循环链表、双向循环链表。 1、单向循环链表: 单向循环链表跟单向链表唯一的区别就在 尾结点 。我们知道,单向链表的尾结点指针指向空地址,表示这就是最后的结点了。而单向循环链表的尾结点指针是指向链表的头结点。从我画的单向循环链表图中,你应该可以看出来,它像一个环一样首尾相连,所以叫作“单向循环”链表。 和单向链表相比,单向循环链表的优点是从链尾到链头比较方便。当要处理的数据具有环型结构特点时,就特别适合采用单向循环链表。比如著名的 约瑟夫问题 。尽管用单向链表也可以实现,但是用单向循环链表实现的话,代码就会简洁很多。 2、双向循环链表: 双向循环链表想必也不用我多说了吧。 二、循环链表实战 假设有这么一个小游戏: 100个人围成圆圈,从1开始报数,喊到3人的时候退出,重复,直到剩下最后一个人。 看到围成圆圈,立马想到了 循环链表 这个数据结构。 1、我们先来定义循环链表的接口 public interface CircularLinkedList < E > { /** * 向链表插入一个元素,默认在尾部 *