文章目录

  • 卷一:数学知识准备篇
    • 数学归纳法
    • 数学归纳法与程序设计
    • 初等数论基础
      • 素数筛算法
      • 余数
      • 欧几里得算法
      • 扩展欧几里得
      • 斐波那契数列
      • 快速幂算法
      • 快速乘算法
      • 矩阵快速幂
    • 练习题: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. Spring Data ElasticSearch示例--查询索引库
  2. Py修行路 python基础 (二十)模块 time模块,random模块,hashlib模块,OS及sys模块...
  3. git 32位_编译64位的BorderlessGaming
  4. Tyvj 1921 Freda的烦恼
  5. 响应式手机配件织梦模板
  6. Bootstrap3 栅格系统之列嵌套
  7. PHP网络操作函数汇总
  8. 计算机专业说课,计算机专业课程说课.ppt
  9. 03、三种简单的计时器
  10. Java Greedy Snake, need to be updated
  11. 【图论】Graph Fourier Transform
  12. Java开发微信小程序(三)用小程序给用户推送服务消息
  13. 使用电信光猫加路由器实现内网穿透,外网访问内网
  14. in作为介词的用法_介词at和in表示地点时的各自用法
  15. QQ小程序内测邀请码内部获取群
  16. php如何计算天数,php计算日期相差天数二种方法
  17. Hadoop3.2.0 HDFS HA ( Quorum Journal Manager )
  18. 快速批量创建文件夹、文件的快捷键
  19. KK版本和L版本编绎camera参数命
  20. 为什么properties中没有load方法_为什么游戏戒不掉?或许你没有找对正确方法

热门文章

  1. angular ngzorro 表格用自定义指令实现自由缩放列宽
  2. 安兔兔苹果html5排行榜,跑分最高的苹果手机iOS设备性能排行榜
  3. VC项目清理工具v1.1
  4. 设置Oracle跟随系统一起启动
  5. 【C4D周练作业071-080】微软的毛玻璃效果
  6. 【IDEA】SpringBoot --could not autowire
  7. 隔空投送所有人安全吗_安卓版隔空投送要来了:谷歌亲自打造,功能比苹果更强...
  8. Hyperledger Fabric实践:供应链金融案例
  9. js触发php事件,JavaScript_代码触发js事件(click、change)示例应用,Chrome , Firfox 不支持fireEvent的方 - phpStudy...
  10. linux命令冒号加叹号,【转载】Linux中的叹号命令