230 likes | 361 Views
ACM 实践周课程(二). 结构体排序. 学习目标. 理解复杂度和 ACM 中的空间时间限制 学会使用常量表简化代码 熟练掌握 STL 中的快速排序 sort 函数 学会为结构体设计构造函数,输入输出函数 学会为结构体重载“小于”运算符 理解快速幂取模. 复杂度. 时间复杂度,简单来说,就是程序执行的步数 估计复杂度的方法: 常数复杂度表示和输入的规模无关 一个 n 次循环,里面如果只有常数步操作,那复杂度就是 O(n) ,如果循环里面还嵌套着一个 n 次循环,那复杂度就是 O(n 2 ) 常见问题的时间复杂度 :
E N D
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}; • 字符串数组 chars[][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小的在前。 • 计算机不知道如何对结构体比较大小 • 所以你应该告诉计算机。
对结构体排序 有两种方法可以告诉计算机如何对结构体排序: • 重载小于号: 对应于 sort(a, a+5); • 写一个比较函数:对应于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(); • 输出函数也是一样的
结构体的构造函数 • 结构体名(参数) { } • 有时候不想写默认构造函数,那么可以给所有的参数加上默认值。
练习 重载小于运算符,把一个点数组按照到点(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) • 如果p最低位为1,则res = res*d。 • d = d*d , p = p>>1; 最终的res即为结果。
快速幂取模 • p d p的最后一位 res • 100111 A 1 1*A = A • 10011 A2 1 A*A2=A3 • 1001 A4 1 A3*A4=A7 • 100 A8 0 A7 • 10 A16 0 A7 • 1 A32 1 A7*A32=A39