文章目录

  • 卷一:数学知识准备篇
    • 数学归纳法
    • 数学归纳法与程序设计
    • 初等数论基础
      • 素数筛算法
      • 余数
      • 欧几里得算法
      • 扩展欧几里得
      • 斐波那契数列
      • 快速幂算法
      • 快速乘算法
      • 矩阵快速幂
    • 练习题:HZOJ.317幸运八

卷一:数学知识准备篇

数学归纳法

  1. 证明P(1)
  2. 假设P(k)正确 --> 证明P(k+1)
  3. 证毕,P(n)正确

数学归纳法与程序设计

  1. 循环累加求和

  2. 递归求阶乘

  3. HZOJ-236 递归实现组合型枚举 oj.haizeix.com

int main(){int sum = 0;for(int i = 1; i <= 100; i++){sum += i;}cout << sum << endl;return 0;
}
int f(int n){if(n == 1) return 1;return n * f(n - 1);
}int main(){cout << f(5) << endl;return 0;
}
void output(int n, int m, int p, vector<int> &buff){
//从n个数字中选m个数字,p:当前可以选择的最小数字
//buff:当前已经选的数字if(buff.size() == m){for(int i = 0; i < m; i++){if(i != 0) cout << " ";cout << buff[i];}cout << endl;return;}//buff数量不足m的情况for(int i = p; i <= n; i++){buff.push_back(i);//继续添加元素output(n, m, i + 1, buffer);//继续往下递归调用,达到m就输出一种方案//输出结束后,把不应该存在buff末尾的元素删除buff.pop_back();}return;
}int main(){int n, m;cin >> n >> m;vector<int> buff;output(n, m, 1, buff);return 0;
}

了解数学归纳法平时更多的是为了保证程序设计的正确性,即使是复杂程序设计也一样。

初等数论基础

素数筛算法

//define MAX_N 10000
int prime[MAX_N + 5] = {0};
//被标记的i为1,没被标记为0
void init_prime(){for(int i = 2; i * i <= MAX_N; i++){if(prime[i]) continue;//i被标记了就继续//用j把i的倍数都标记for(int j = i * i; j <= MAX_N; j += i) prime[j] = 1;}//prime[0]:记录的是表中素数的个数  prime[0]前面存的是素数表,后面存的是标记信息for(int i = 2; i <= MAX_N; i++){//把所有素数整理到prime前半段if(prime[i] == 0) prime[++prime[0]] = i;}return;
}
int main(){init_prime();cout << "total prime : " << prime[0] << endl;int x;while(cin >> x){printf("prime[%d] = %d\n", x, prime[x]);}return 0;
}

余数

  1. x + d = y + d (mod n)
  2. x - d = y - d (mod n)
  3. x * d = y * d (mod n)
  4. a % b 可以写成 a - kb
  5. 以及注意逆元的概念 y * y` = 1

欧几里得算法

整数a,b的最大公约数一般表示为gcd(a, b)终极奥义:gcd(a, b) = gcd(b, a%b)

证明Ⅰ: b和a%b的最大公约数,也是a和b的公约数

证明Ⅱ: b和a%b的最大公约数也是a和b的最大公约数

int gcd(int a, int b){if(b == 0) return a;return gcd(b, a % b);
}int main(){int a, b;while(cin >> a >> b){printf("gcd(%d, %d) = %d\n", a, b, gcd(a, b));}return 0;
}

扩展欧几里得

  1. ax 三 1 (mod b)
  2. ax % b = 1
  3. ax - kb = 1
  4. ax + by = 1
int ex_gcd(int a, int b, int &x, int &y){if(b == 0){x = 1, y = 0;return a;}int nx, ny;//代表下一层的整数解int r = ex_gcd(b, a % b, nx, ny);x = ny;y = nx - a / b * ny;return r;
}int main(){int a, b;while(cin >> a >> b){c = ex_gcd(a, b, x, y);printf("%d * %d + %d * %d = %d\n", a, x, b, y, c);}return 0;
}

贝祖等式:ax + by = gcd(a, b) = c

int ex_gcd(int a, int b, int &x, int &y){if(b == 0){x = 1, y = 0;return a;}int nx, ny;//代表下一层的整数解int r = ex_gcd(b, a % b, nx, ny);x = ny;y = nx - a / b * ny;return r;
}
//修改一下变成求逆元的方法
int inv(int a, int b){int x, int y;ex_gcd(a, b, x, y);x %= b;x += b;x %= b;return x;//通过上面三步,x肯定变成了正数}int main(){int a, b;while(cin >> a >> b){printf("%d * %d %% %d = 1\n", a, inv(a, b), b);}return 0;
}

斐波那契数列

  1. F(0) = 0, F(1) = 1
  2. F(n) = F(n-1) + F(n-2)
  3. 0, 1, 1, 2, 3, 5, 8, 13, 21
  4. F(n+m) = F(m)F(n+1) + F(m-1)F(n)
//蓝色斜杠是c/c++特殊语法
#define TEST(func){\long long b, e;\b = clock();\func;\e = clock();\printf("Run %lld ms\n", (e - b) * 1000 / CLOCKS_PRE_SEC);\
}unordered_map<int, int> f_result; //哈希表
long long f(long long n){if(n <= 2) return !!(n);//归一化: 0=>0 非0=>1if(f_result.find(n) == f_result.end()){//如果没计算过就重新计算long long a = n / 2, b = n - a;long long val1 = f(b), val2 = f(a + 1), val3 = f(b - 1),val4 = f(a);f_result[n] = (val1 * val2 + val3 * val4) % 9973;}return f_result[n];
}
long long normal_f(long long n){long long a = 0, b = 1;for(int i = 0; i < n; i++){b = (a + b) % 9973;a = b - a;}b = (b + 9973) % 9973;return b;
}
int main(){long long n;while(cin >> n){TEST(printf("f[%lld] = %lld\n", n, normal_f(n)));TEST(printf("f[%lld] = %lld\n", n, f(n)));}return 0;
}

快速幂算法

int quick_power(int a, int b){int ans = 1, temp = a;while(b){if(b % 2) ans *= temp;//b的末尾是奇数时temp *= temp;b /= 2;//去掉二进制末尾那个值}return ans;
}
int main(){int a, b;while(cin >> a >> b){printf("%d^%d = %d\n", a, b, quick_power(a, b));}return 0;
}

快速乘算法

//适用于 a*b 超界的情况
int quick_mul(int a, int b){int ans = 0, temp = a;while(b){//当b!=0时if(b % 2) ans += temp;//如果b末尾是1 累加temp += temp;b /= 2;}return ans;
}int main(){int a, b;while(cin >> a >> b){printf("%d * %d = %d\n", a, b, quick_mul(a, b));}return 0;
}

矩阵快速幂

//解决形如 F(n) = aF(n - 1) + bF(n - 2)
class Matrix {//初始化n行m列矩阵
public:Matrix(int n, int m, int e = 0) : n(n), m(m) {for(int i = 0; i < n; i++) c.push_back(vector<long long>(m, 0));for(int i = 0; i < n; i++) c[i][i] = 1;}vector<long long> &operator[](int ind){ return c[ind];}Matrix &operator%(int x){//矩阵取余for(int i = 0; i < n; i++){for(int j = 0; j < m; j++){c[i][j] %= x;}}return *this;}Matrix operator*(const Matrix &obj){//矩阵乘法Matrix ret(n, obj.m);//结果矩阵for(int i = 0; i < n; i++){for(int j = 0; j < obj.m; j++){ret[i][j] = 0;for(int k = 0; k < m; k++){ret[i][j] += c[i][k] * obj.c[k][j];}}}return ret;}
private:int n, m;vector<vector<long long>> c;
};Matrix quick_power(Matrix a, int b){Matrix ans(2, 2, 1), temp = a;//两行两列的单位矩阵while(b){if(b % 2) ans = ans * temp % 9973;temp = temp * temp % 9973;b /= 2;}return ans;
}int main(){Matrix a(2, 2);//初始化系数矩阵a[0][0] = 1, a[0][1] = 1, a[1][0] = 1, a[1][1] = 0;int n;while(cin >> n){Matrix b = quick_power(a, n);//b矩阵等于a矩阵的n次方printf("f[%d] = %lld\n", n, b[1][0]);}         return 0;
}

练习题:HZOJ.317幸运八

题目:众所周知,八是一个吉利数字。现给定一个数字N,求最短能被N整除的只由8组成的数字的长度

相当于:8(10^x - 1) / 9 - k * n = 0 的最小的x值 (10^x - 1) - k (9n) / 8 = 0 k中和9n都包含一部分8

9n` = 9n / gd(n, 8)

(10^x - 1) - k(9n`) = 0

10^x = 1 (mod 9n`)

gd(10, 9n`) = 1

long long gcd(long long a, long long b){if(b == 0) return a;return gcd(b, a % b);
}long long phi(long long n){long long i = 2, x = n;while(i * i <= x){if(x % i == 0) n -= (n / i);while(x % i == 0) x /= i;i += 1;}if(x != 1) n -= (n / x);return n;
}
long long quick_mul(long long a, long long b, long long c){long long ans = 0, temp = a;while(b){//当b!=0if(b & 1) ans = (ans + temp) % c;//b的最后一位是1temp = (temp + temp) % c;b >>= 1;}return ans;
}long long quick_mod(long long a, long long b, long long c){//快速幂long long ans = 1, temp = a;while(b){//if(b & 1) ans = ans * temp % c;//这里可能超过范围 需改写if(b & 1) ans = quick_mul(ans, temp, c);//快速乘 加法temp = quick_mul(temp, temp, c);b >>= 1;}return ans;
}set<long, long> getSet(long long x){//unordered_set无序   set是有序表long long i = 2;set<long, long> h, temp;//两个哈希表h.insert(1);//初始化表while(i * i <= x){while(x % i == 0){for(auto y : h) temp.insert(y * i);//遍历哈希表中的所有数字 乘以i 并且重新插入到哈希表中for(auto y : temp) h.insert(y);//将temp表的数据插入到tempx /= i;}i += 1;}if(x != 1){//说明x自己是素数temp.clear();for(auto y : h){//cout << "insert : " << y * x << endl;temp.insert(y * x);}for(auto y : temp) h.insert(y);}return h;
}int main(){long long n, x;cin >> n;n *= 9;n /= gcd(n, 8)//n和8的最大公约数if(gcd(n, 10) != 1){//没有答案的时候printf("0\n");//输出0return 0;}x = phi(n);//欧拉函数值auto x_set = getSet(x);//获得x所有的因子//cout << x << endl;//输出x的值for(anto i : x_set){//需要优化 快速枚举因子 -> 遍历 if(x % i) continue;if(quick_mod(10, i, n) != 1) continue;cout << i << endl;//printf("%lld\n", i);break;}return 0;
}

《计算机程序设计艺术》读书笔记(一)相关推荐

  1. mysql数据库权威指南_MySQL_MySQL权威指南读书笔记(三),第二章:MYSQL数据库里面的数 - phpStudy...

    MySQL权威指南读书笔记(三) 第二章:MYSQL数据库里面的数据 用想用好MYSQL,就必须透彻理解MYSQL是如何看待和处理数据的.本章主要讨论了两个问题:一是SQL所能处理的数据值的类型:二是 ...

  2. MongoDB权威指南读书笔记——CRUD

    插入并保存文档 插入是向MongoDB中添加数据的基本方法.可以使用Insert方法向目标集合插入一个文档:db.foo.insert({"bar" : "baz&quo ...

  3. HTTP权威指南读书笔记

    <<HTTP权威指南>>读书笔记 第一部分:Web的基础 第1章:HTTP概述 主要内容 1.什么是HTTP 2.HTTP的基本组件 HTTP HTTP:HTTP(Hypert ...

  4. HTML5权威指南----读书笔记

    <!DOCTYPE html> <html> <head><meta name = 'keywords' content="HTML5权威指南--- ...

  5. 计算机网络和http权威指南 读书笔记

    计算机网络笔记 网络层 网络层向上提供无连接的,尽最大努力交付的数据报服务 网络层不提供数据质量承诺 物理层使用的中间设备叫转发器repeater 数据链路层叫网桥bridge 网络层叫路由器rout ...

  6. MapReduce总结 + 相关Hadoop权威指南读书笔记(未完......欢迎补充,互相学习)

    文章目录 MapReduce概述 MapReduce优缺点 MapReduce核心思想 MapReduce进程 MapReduce编程规范 WordCount 案例实操 本地测试 集群测试 Hadoo ...

  7. android开发读书笔记,android开发权威指南读书笔记

    第17章 Fragment 1.在res目录下增加 layout-sw600dp 目录,用于存放7英寸及以上尺寸屏幕的布局文件.10英寸以上平板用 sw720dp.如果是更小的屏幕,如 480*800 ...

  8. java性能权威指南中文_Java性能权威指南读书笔记--之一

    JIT(即时编译) 解释型代码:程序可移植,相同的代码在任何有适当解释器的机器上,都能运行,但是速度慢. 编译型代码:速度快,电视不同CPU平台的代码无法兼容. java则是使用java的编译器先将其 ...

  9. javascript权威指南读书笔记之二——词法结构

    本章讲述的内容,用通俗的语言来说,就是应该注意的地方,这些也许和我们所学的其他语言类似,也许完全不同,比如一开始就介绍说javascript程序中的每个字符都是用两个字节表示的,但有些程序设计者习惯于 ...

  10. HTTP权威指南读书笔记(一)HTTP概述、URL和资源及报文详解

    一.HTTP概述 1.WEB客户端和服务器. 2.资源:资源可以是各种格式的静态文件,也可以是应用程序. 3.媒体类型 4.URI:统一资源标识符 URL:统一资源定位符. URL的第一部分称为方案: ...

最新文章

  1. 使用Redis分区将数据分割到多个Redis实例
  2. PowerDesigner使用方法入门学习
  3. [codeVS1204] 单词背诵
  4. Redis如何淘汰过期的keys
  5. oracle查询使用or,查询视图,使用or就用不上索引
  6. nacos 公共_SpringCloud配合注册中心Nacos的使用
  7. 数据结构——二叉树的层次遍历
  8. [密码学基础][每个信息安全博士生应该知道的52件事][Bristol Cryptography][第5篇]复杂性类NP是什么意思?
  9. LeetCode 688. “马”在棋盘上的概率(DP)
  10. 与40mhz信道不兼容设置_为什么面包板不适合高频电路
  11. Python中的回文详解
  12. centos6安装mysql并远程连接_阿里云服务器上安装redis并实现远程连接
  13. 数据库系统概论王珊编写的第三章学生-课程数据库
  14. python itemgetter函数用法_Python itemgetter函数怎么用?
  15. 删除某文件以外的文件
  16. (转贴) ArcIMS初级教程(1)
  17. RGB图像转为灰度图像原理
  18. android系统中使用ksoap2-android客户端库操作Asp.net WebService
  19. Scala入门(2)
  20. 简单控制台项目:电影购票系统

热门文章

  1. JavaScript模板引擎Template.js使用
  2. 硬件的组成配件及功能
  3. Window下进行PHP的redis扩展安装
  4. Vue响应式原理简述
  5. 13-Qt使用Ps制作软件启动图标和应用内图标的一般方法于步骤
  6. java回文数字判断,java 实现判断回文数字的实例代码
  7. PHP 关于数组的6个处理
  8. 用友NC产品接口开发,通过轻易云数据集成平台快速调用
  9. matlab编写fie滤波器,数字信号处理大作业mdash;mdash;基于matlab R2019a的男声变女声资料汇总与代码...
  10. 面试题--字符串拷贝函数