1、实现求乘法逆元的函数,给定a和m,求a模m的乘法逆元,无解时请给出无解提示,并且只返回正整数。 进而给出求解同余方程(ax = b mod m)的函数,即给定a,b,m,输出满足方程的x,无解给出无解提示。 2、实现模指数运算的函数,给定x、y和m,求x的y次方模m。 3、设p = 23和a = 5,使用费尔马小定理计算a^{2020} mod p? 4、使用欧拉定理计算2^{100000} mod 55。 5、手动计算7^{1000}的最后两个数位等于什么?
代码很多,分量很足,写了一天,菜鸡一条。很糟心的是CSDN的博客,代码是不能折叠的。(找了半个多小时代码折叠,最后有个博客直说了,“CSDN的博客暂不支持”:Markdown中实现内容及代码块折叠 *** 作)
只能说这博客的内容编辑是挺混乱的,乱七八糟可以说是。“高亮”、“加粗”、“斜体”、“字体大小”之类的基本能用html标签代替,“空格”、“换行”、“字体颜色”只能用html标签实现。嘛,算了,谁没事去写博客啊。
代码
弄了一堆的文件,简述如下:
【GlobalSet.h】:声明了一堆要用的函数(模板是没法把定义扔进cpp文件的)
【GlobalSet.cpp】:完成GlobalSet.h里头声明的函数的定义(用了static变量防变量“外出”)
【Test1.cpp】:题目1的代码
【Test2.cpp】:题目2的代码
【Test3.cpp】:题目3的代码
【Test4.cpp】:题目4的代码
【Test5.cpp】:题目5的代码
【Main.cpp】:就main主函数而已,调用上面那几个Test.cpp文件写好的函数
GlobalSet.h
//GlobalSet.h #pragma once #ifndef GLOBALSET_H #define GLOBALSET_H #includeGlobalSet.cppusing namespace std; typedef unsigned int uint; vector EGCD(int a, int b);//新写的EGCD。之前作业二写的EGCD弃用 uint Inverse_Multi(int a, uint m);//模m下a的乘法逆元(无解时返回0 uint Mod(int x, uint m);//求x%m uint Pow(int x, int y, uint m);求x^y (mod m)。m=0时不取模 bool IsPrime(uint m);//判断是否为素数 uint PHI(uint m);//欧拉函数φ(m) template //模板的定义和声明不能分离。(这个函数没什么实用,还浪费了不少时间编写。单纯就练习算法了(但还写的贼烂) static int Search(vector & lst, T val) {//寻找成功时返回下标,失败则返回-1 if (lst.empty()) return -1; uint left = 0; uint right = lst.size() - 1; if (lst[left] > lst[right]) { left = right; right = 0; } struct { uint L : 1;//这位域感觉没啥用,算了就这样留着 uint M : 1; uint R : 1; uint : 29; }flag{ 0 }; while (true) {//二分法查找 uint mid = (left + right) / 2; if (mid == left || mid == right) break; flag.L = lst[left] < val; flag.M = lst[mid] < val; flag.R = lst[right] < val; if ((flag.R == flag.M)) right = mid; else left = mid; } if (lst[left] == val) return left; if(lst[right]==val) return right; return -1; } #endif
#include"GlobalSet.h" #includeMain.cpp
//Main.cpp #include"GlobalSet.h" void Test1(); void Test2(); void Test3(); void Test4(); void Test5(); int main() { Test1(); Test2(); Test3(); Test4(); Test5(); return 0; }Test1.cpp
//Test1.cpp #include"GlobalSet.h" static vectorTest2.cppSolveFunction_1(int a, int b, uint m) {//解决题1给出的方程题:Ax≡B (mod m) vector result; if (m > 0) { b=Mod(b, m); auto rst = EGCD(a, m); if (b % rst[2] == 0) { auto r = rst[0] * (b / rst[2]); auto step = m / rst[2]; while (r < 0) r += step; r %= m; for (auto n = 0; n++ < rst[2]; r += step) { result.push_back(r); } } } return result; } void Test1_1() { int m = 12; vector testNum{3,7,12,-5,29,39,-35}; printf("【题目1.1(求乘法逆元)】n"); for(auto p=testNum.begin();p!=testNum.end();++p) printf("ta=%-7d m=%-7d 1/a=%-7dn", *p, m, Inverse_Multi(*p, m)); printf("nn"); } void Test1_2() { vector >testNum;//格式为[(a,b,m) , (a,b,m) , (a,b,m),...] testNum.push_back(vector {4, 8, 10}); testNum.push_back(vector {5, 1, 12}); testNum.push_back(vector {6,-3,15}); testNum.push_back(vector {-7,7,9}); testNum.push_back(vector {-5,-7,13}); testNum.push_back(vector {6,5,12}); testNum.push_back(vector {7,53,12}); testNum.push_back(vector {-48,-37,5}); printf("【题目1.2(求解同余方程Ax≡b(mod m))】n"); for (auto p = testNum.begin(); p != testNum.end(); ++p) { auto rst = SolveFunction_1((*p)[0], (*p)[1], (*p)[2]); printf("%7dx≡%dt( mod %d )tx=",(*p)[0], (*p)[1], (*p)[2]); if (rst.empty()) printf("* "); else { for (auto p = rst.begin(); p != rst.end(); ++p) printf("%d,", *p); } printf("b n"); } printf("nn"); } void Test1() { Test1_1(); Test1_2(); }
//Test2.cpp #include"GlobalSet.h" void Test2() { vectorTest3.cpp>testNum;//格式为[(x,y,m) , (x,y,m) , (x,y,m),...] testNum.push_back(vector {-7, 5, 0});//模为0时不取模 testNum.push_back(vector {-7, -5, 0});//不取模时负数幂所得结果为0 testNum.push_back(vector {-7, 5, 10});//系统自带计算器,模式切换为科学计算可对运算结果进行检验 testNum.push_back(vector {5, -3, 10});//负数幂需要求逆元,当逆元不存在时结果为0 testNum.push_back(vector {9, -3, 10});//系统自带计算器对负数幂无法检验(主要是求不了逆元) testNum.push_back(vector {15, 23, 13}); testNum.push_back(vector {-12, 63, 15}); testNum.push_back(vector {-55, -47, 29}); testNum.push_back(vector {-18, -19, 34}); printf("【题目2(实现模指数运算)】n"); for (auto p = testNum.begin(); p != testNum.end(); ++p) { printf("%7d ^ %-7d = %-12d( mod %d )n", (*p)[0], (*p)[1], Pow((*p)[0], (*p)[1], (*p)[2]), (*p)[2]); } testNum.clear(); testNum.push_back(vector {5, 2020, 23}); testNum.push_back(vector {43, 3548, 89}); testNum.push_back(vector {54, -1986, 47}); testNum.push_back(vector {-54, 2021, 37}); testNum.push_back(vector {-73, -2021, 79}); printf("n"); for (auto p = testNum.begin(); p != testNum.end(); ++p) { printf("%7d ^ %-7d = %-12d( mod %d )n", (*p)[0], (*p)[1], Pow((*p)[0], (*p)[1], (*p)[2]), (*p)[2]); } testNum.clear(); testNum.push_back(vector {2, 100000, 55}); testNum.push_back(vector {-5, 2020, 248}); testNum.push_back(vector {43, -3548, 96}); testNum.push_back(vector {-54, -1986, 47}); printf("n"); for (auto p = testNum.begin(); p != testNum.end(); ++p) { printf("%7d ^ %-7d = %-12d( mod %d )n", (*p)[0], (*p)[1], Pow((*p)[0], (*p)[1], (*p)[2]), (*p)[2]); } printf("nn"); }
//Test3.cpp #include"GlobalSet.h" static uint Pow_Fermat(int a,int b,uint p) {//使用费马小定理,计算a^b (mod p) 。p为素数,如果不是素数则返回0 if (IsPrime(p) == false) return 0; return Pow(a, Mod(b,p-1), p); } void Test3() { vectorTest4.cpp>testNum;//格式为[(a,b,p) , (a,b,p) , (a,b,p) ,...] testNum.push_back(vector {5, 2020, 23}); testNum.push_back(vector {43, 3548, 89}); testNum.push_back(vector {54, -1986, 47}); testNum.push_back(vector {-54, 2021, 37}); testNum.push_back(vector {-73, -2021, 79}); printf("【题目3(使用费马小定理实现模指数运算)】n"); for (auto p = testNum.begin(); p != testNum.end(); ++p) { printf("%7d ^ %-7d = %-12d( mod %d )n", (*p)[0], (*p)[1], Pow_Fermat((*p)[0], (*p)[1], (*p)[2]), (*p)[2]); } printf("nn"); }
//Test4.cpp #include"GlobalSet.h" static uint Pow_Euler(int a, int b, uint p) {//使用欧拉定理,计算a^b (mod p) return Pow(a, Mod(b,PHI(p)), p); } void Test4() { vectorTest5.cpp>testNum;//格式为[(a,b,p) , (a,b,p) , (a,b,p) ,...] testNum.push_back(vector {2, 100000, 55}); testNum.push_back(vector {-5, 2020, 248}); testNum.push_back(vector {43, -3548, 96}); testNum.push_back(vector {-54, -1986, 47}); printf("【题目4(使用欧拉定理实现模指数运算)】n"); for (auto p = testNum.begin(); p != testNum.end(); ++p) { printf("%7d ^ %-7d = %-12d( mod %d )n", (*p)[0], (*p)[1], Pow_Euler((*p)[0], (*p)[1], (*p)[2]), (*p)[2]); } printf("nn"); }
//Test5.cpp #include"GlobalSet.h" #includevoid Test5() { printf("【题目5(手动计算7^{1000}的最后两个数位)】n"); cout<<"求最后两位数,等价于计算7^1000的模100后的结果,即求解7^1000 (mod 100)"<
运行结果
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)