函数和递归

Download Report

Transcript 函数和递归

ACM实践周课程(二)
结构体排序
学习目标
 理解复杂度和ACM中的空间时间限制
 学会使用常量表简化代码
 熟练掌握STL中的快速排序sort函数
 学会为结构体设计构造函数,输入输出函数
 学会为结构体重载“小于”运算符
 理解快速幂取模
复杂度
 时间复杂度,简单来说,就是程序执行的步数
 估计复杂度的方法:
 常数复杂度表示和输入的规模无关
 一个n次循环,里面如果只有常数步操作,那复
杂度就是O(n),如果循环里面还嵌套着一个n次
循环,那复杂度就是O(n2)
 常见问题的时间复杂度:
二分查找 O(logN) , 快速排序 O(NlogN)
ACM的时间限制
 一般而言时间限制为1到30秒。
 现在计算机1秒执行的指令数量级在109
 所以程序的复杂度最多在107到108之间,而且越
大就越要注意常数优化。
 n如果是10000,那最好不要使用O(n2)的算法。
 n如果是500,那最好不要使用O(n3)的算法。
ACM的空间限制
 在OJ上一般都是32Mb到128Mb。所以int类型的
数组最多能开到8*106数量级。二维的不要超过
2500*2500。当然,这得根据题目来确定。
 另外,由于调用栈的大小有限,大数组不要写
在函数里面,而应定义成全局的。
 一般而言,如果空间超过限制,那么时间也很
可能超限制。
常数优化策略
 一般如果循环可以交换,那么次数少的循环写
外层,次数多的循环写内层。
 浮点数运算比较慢,除法和取模运算比较慢,
位运算比较快。如果除数是2的整数次幂,使用
位运算比较好。
学会使用常量
#define MAXN 1000
const int MAXN = 1000;
定义数组:int data[MAXN] = {0};
字符串数组
char s[][20] = {“Alice”,“Bob”,“Chris”};
char *s[20] = {“Alice”,“Bob”,“Chris”};
s[i]表示第i个字符串。
QWE
 如果把手向右移动一个位置,想打Q时会打出W,




想打J会打成K。
如果给出打错之后的字符串(均为可见字符),输
出本来想打的句子。
例如:
输入 O S, GOMR YPFSU/
输出 I AM FINE TODAY.
QWE
 很多个if判断??
(代码冗长,错误不易察觉)
 定义字符串
 接入一个字符,在s中找到它,打出它前面一个。
 注意反斜杠字符 \ 需要转义。类似的还有双引
号,单引号。
STL的快速排序函数(sort)
 qsort需要用指针,而且写起来不方便。
 sort的格式:
sort(首地址,首地址+排序元素个数,[比较函数] );
比如数组 int a[5] = {4, 6, 7, 2, 3};
sort(a, a+5); //从小到大
sort(a, a+5, greater<int>() ) //从大到小
对结构体排序
 struct Point{ int x, y; };
 如何对一个Point数组进行排序呢?按照x小的在
前,如果相同则按y小的在前。
 计算机不知道如何对结构体比较大小
 所以你应该告诉计算机。
对结构体排序
有两种方法可以告诉计算机如何对结构体排序:
1.重载小于号: 对应于 sort(a, a+5);
2.写一个比较函数:对应于sort(a, a+5, cmp);
结构体的输入输出
 一个结构体往往有比较多的成员变量,如果要
对它们进行输入,可以写成:
for(int i=0; i<n; ++i)
scanf(“%d%d”, &p[i].x, &p[i].y);
 如果成员比较多,写起来不好看。
 可以对结构体写一个input函数:
for(int i=0; i<n; ++i)
p[i].input();
 输出函数也是一样的
结构体的输入输出
利用sort对结构体排序
结构体的构造函数
 结构体名(参数) { }
 有时候不想写默认构造函数,那么可以给所有的
参数加上默认值。
练习
重载小于运算符,
把一个点数组按照
到点(0,0)的距离
从大到小进行排序
ACM算法列表
 百度搜索 ACM算法列表
 基础算法
 搜索
 数据结构
 动态规划
 数学&&计算几何
 图论&&网络流
快速幂取模
 问题, 给定正整数a,p,m,计算 ap % m。
 a<=109, p<=109, m<=105
 已知(a*b) % c = ( (a%c) * (b%c) ) % c
 暴力??109!
快速幂取模









一个数表示成二进制
(39)10 = (100111)2
39 = 1*25 + 0*24 + 0*23 + 1*22 + 1*21 + 1*20
A39 = A32 * A4 * A2 * A1
如何计算A32,A4,A2 这种形如 A2^n的值?
A1 * A1 = A2
A2 * A2 = A4
A4 * A4 = A8
A2^n-1 * A2^n-1 = A2^n
快速幂取模
 用一个变量d表示A2^k, k从0开始,即初始d = A
 用一个变量res表示返回的结果,初始 res = 1。
 计算A^p
while(p!=0)
1. 如果p最低位为1,则res = res*d。
2. d = d*d , p = p>>1;
最终的res即为结果。
快速幂取模







p
100111
10011
1001
100
10
1
d
p的最后一位
A
1
A2
1
A4
1
A8
0
A16
0
A32
1
res
1*A = A
A*A2=A3
A3*A4=A7
A7
A7
A7*A32=A39
THANK YOU!