第二章末尾的上机题目有很多道,其中和数论有关的是最值得做的:
12.已知两个正整数,用欧几里德算法求其最大公约数
13.已知两个正整数,用欧几里德算法求其最小公倍数
14.1 已知一个正整数,求n以内的素数
14.2已知一个整数,验证是否包含某个因子,检查m是否包含n的若干次方
14.已知一个正整数,求其素因子分解
15.已知一个正整数n和一个大于1的正整数b,求n的b进制展开
16.已知3个大于1的正整数a,b,n,求a^bmod m
17.已知一个正整数,求其康托展开
18.用线性同余(≡)发生器 x(n+1)=( a*x(n)+c) mod m, x(0)=b 生成一列n个伪随机数。
19.已知正整数a和b,求整数s和t使得sa+tb=gcd(a,b)
20.求同余幂
21.求中国余数问题方程组的解
22.模拟rsa编码解码
用VC实现的习题,运行通过。
- #include "stdafx.h"
- #include<algorithm>
- #include<deque>
- #include<iostream>
- #include<ostream>
- #include<map>
- #include<math.h>
- #include<vector>
- #pragma warning(disable:4786)
- using namespace std;
-
- int gcd(int m,int n){
- if(n==0)return 0;
- while(n){
- int temp=n;
- n=m%n;
- m=temp;
- }
- return m;
- }
-
- int lcm(int m,int n){
- if(m==0||n==0)return 0;
- return m*n/gcd(m,n);
- }
-
- vector<int> primes(int n){
- vector<int> vi;
- if(n==0){
- vi.push_back(0);
- return vi;
- }
- else if(n<0){
- vi.push_back(-1);
- }
- for(int i=2;i<n;++i){
- int s=vi.size();
- int c=0;
- for(;c<s;++c){
- if(gcd(i,vi[c])!=1)break;
- }
- if(c==s)
- vi.push_back(i);
- }
- return vi;
- }
-
- int contains(int m,int n){
- int mod=m%n;
- if(mod)return 0;
- else{
- int i=0;
- while(!mod){
- ++i;
- m/=n;
- mod=m%n;
- if(m==1)break;
- }
- return i;
- }
- }
-
- map<int,int> divide(int n){
- map<int,int> mi;
- if(n==0 || n==1){
- mi[n]=1;
- return mi;
- }
- if(n<0){
- n=-n;
- mi[-1]=1;
- }
- int nsqrt=(int)sqrt(n);
- vector<int>& vi=primes(nsqrt);
- for(vector<int>::iterator it=vi.begin();it!=vi.end();++it){
- int mod=n%*it;
- if(!mod){
- mi[*it]=contains(n,*it);
- }
- }
- return mi;
- }
- void printDivide(const map<int,int>& mi){
- for(map<int,int>::const_iterator it=mi.begin();it!=mi.end();++it){
- cout<<it->first<<'^'<<it->second<<',';
- }
- }
- void printExtend(const map<int,int>& mi){
- for(map<int,int>::const_iterator it=mi.begin();it!=mi.end();++it){
- cout<<it->second<<'*'<<it->first<<"!+";
- }
- }
-
- deque<int> exp(int n,int b){
- deque<int> di;
- if(n<=0 || b<=1 || n<b){
- di.push_back(0);
- return di;
- }
- int d=1,m=0;
- do{
- d=n/b;
- m=n%b;
- di.push_front(m);
- n=d;
- }while(d);
- return di;
- }
-
- int powerDivide(int a,int b,int m){
- if(a<=0||b<=0||m<=0)return -1;
- if(a==1)return 1;
- if(b==1)return a%m;
- if(m==1)return 0;
- deque<int>& di=exp(b,2);
- reverse(di.begin(),di.end());
- int x=1;
- int power=a;
- for(deque<int>::iterator it=di.begin();it!=di.end();++it){
- if(*it==1){
- x*=power;
- }
- x%=m;
- power=(power*power)%m;
- }
- return x;
- }
-
- map<int,int> extend(int n){
- map<int,int> mi;
- deque<int> di;
- if(n<=1)return mi;
- int i=1;
- int x=1;
- do{
- x*=i++;
- di.push_back(x);
- }while(x<n);
- di.pop_back();
-
- for(int s=di.size()-1;s>=0;--s){
- int i=n/di[s];
- n-=i*di[s];
- mi[s+1]=i;
- if(n==0)break;
- }
- return mi;
- }
-
-
-
-
-
-
- vector<int> xrand(int m){
- vector<int> vr;
- if(m<=1)return vr;
- int a=m+1;
- vector<int>& vi=primes(m);
- int c;
- if(m==2)c=1;
- else{
- if(vi.back()==m-1)vi.pop_back();
- c=vi.back();
- }
-
- int b=(a*c)%m;
- int xn=b;
- for(int i=0;i<m;++i){
- vr.push_back(xn);
- xn=((a*xn)+c)%m;
- }
- return vr;
- }
-
-
-
-
-
-
-
- typedef pair<int,int> pi;
- pi revert_gcd(int m,int n){
- pi p;
- if(n==0)return make_pair(0,0);
- if(m==n)return make_pair(1,0);
- deque<int> vi;
- bool less=(m<n);
- while(n){
- int temp=n;
- if(m>n){
- vi.push_back(m/n);
- }
- n=m%n;
- m=temp;
- }
- vi.pop_back();
- int x1=1;
- int x2=-vi.back();
- for(deque<int>::reverse_iterator it=vi.rbegin();it!=vi.rend();++it){
- vi.pop_front();
- if(vi.size()==0)break;
- int temp1=x2;
- int temp2=x1-(x2*vi.front());
- x1=temp1;
- x2=temp2;
- }
- if(less)swap(x1,x2);
- return make_pair(x1,x2);
- }
-
- int rpower(int a,int m){
- if(gcd(a,m)!=1)return 0;
- int r=revert_gcd(a,m).first;
- return (r>0) ? r : r+m;
- }
-
- void rchina(vector<pi>& vp){
- if(vp.size()==0)return;
- for(vector<pi>::iterator it=vp.begin();it!=vp.end();++it){
- int a=it->first;
- int m=it->second;
- if(a<=m){
- cout<<"rchina param error: a="<<a<<",m="<<m<<'\n';
- }
- int g=gcd(a,m);
- if(g!=1){
- vp.erase(it);
- vector<int>& vi=primes(a);
- for(vector<int>::iterator i=vi.begin();i!=vi.end();++i){
- if(gcd(*i,m)==1)vp.push_back(make_pair(*i,m));
- }
- }
- }
- }
- int solchina(vector<pi>& vp){
- rchina(vp);
- size_t len=vp.size();
- vector<int> via(len);
- vector<int> vim(len);
- vector<int> viy(len);
-
- for(int i=0;i<len;++i){
- int a=vp[i].first;
- int m=vp[i].second;
- via[i]=a;
- vim[i]=1;
- for(int j=0;j<len;++j){
- if(i!=j)vim[i]*=m;
- }
- viy[i]=rpower(a,m);
- }
- int ret=0;
- int M=1;
- for(int k=0;k<len;++k){
- ret+=via[k]*vim[k]*viy[k];
- M*=vim[k];
- }
- return ret%M;
- }
-
- int p=43;
- int q=59;
- int e=13;
- int d=rpower(e,(p-1)*(q-1));
- int encode(int m){
- return powerDivide(m,e,p*q);
- }
- int decode(int c){
- return powerDivide(c,d,p*q);
- }
- void printDecode(vector<int>& vi){
- for(vector<int>::iterator it=vi.begin();it!=vi.end();++it){
- int m=decode(*it);
- char buf[1024]={0};
- itoa(m,buf,10);
- cout<<buf<<',';
- }
- }
- int main(int argc, char* argv[])
- {
- int g=gcd(153460,12233440);
- int l=lcm(27,33);
- vector<int>& vi=primes(5);
- copy(vi.begin(),vi.end(),ostream_iterator<int>(cout,","));
- cout<<'\n';
- printDivide(divide(-720));
- deque<int>& di=exp(111,8);
- cout<<"\n111 mod 8=\n";
- copy(di.begin(),di.end(),ostream_iterator<int>(cout,""));
- cout<<'\n';
- cout<<"\n2^9 mod 5 ="<<powerDivide(2,9,5)<<'\n';
- map<int,int>& me=extend(10);
- printExtend(me);
- vector<int>& vr=xrand(12);
- cout<<'\n';
- copy(vr.begin(),vr.end(),ostream_iterator<int>(cout,","));
- cout<<'\n';
- pi& p=revert_gcd(252,198);
- cout<<"\ngcd(252,198)="<<gcd(252,198)<<'='<<"252*("<<p.first<<")+198*("<<p.second<<")\n";
- cout<<"rpower(3,7)="<<rpower(3,7)<<'\n';
- vector<int> v;
- v.push_back(0667);
- v.push_back(1947);
- v.push_back(0671);
- printDecode(v);
- return 0;
- }
运行后输出:
2,3,
-1^1,2^4,3^2,5^1,
111 mod 8=
157
2^9 mod 5 =2
2*2!+1*3!+
7,2,9,4,11,6,1,8,3,10,5,0,
gcd(252,198)=18=252*(4)+198*(-5)
rpower(3,7)=5
1579,1475,1288
--------------------------------------------------------------------------
还有几个习题中出现的上机算法题,也都用VC2010实现。几种常见的排序算法
- #include "stdafx.h"
- #include<algorithm>
- #include<iostream>
- #include<iterator>
- #include<functional>
- using namespace std;
-
-
- template<typename Func>
- void bubleSort(int* pv,int count,Func f){
- for(int i=0;i<count-1;++i){
- for(int j=0;j<count-1-i;++j){
- if( !f(pv[j],pv[j+1]))swap(pv[j],pv[j+1]);
- }
- }
- }
-
-
- template<typename Func>
- void InsertSort( int *pSortDest, int *pSortSrc, size_t nSort, Func compare )
- {
- if( pSortDest == NULL || pSortSrc == NULL || nSort == 0 )
- {
- return;
- }
- size_t nDone = 0;
- while( nSort )
- {
- int& nNext = pSortSrc[ nDone ];
- size_t L = 0;
- for( ; L < nDone; ++L )
- {
- if( ! compare(nNext, pSortDest[ L ]) )
- {
- continue;
- }
- else
- {
- break;
- }
- }
-
-
- for( size_t move = nDone; move > L ; --move )
- {
- pSortDest[ move ] = pSortDest[ move - 1 ];
- }
- pSortDest[ L ] = nNext;
- --nSort;
- ++nDone;
- }
- }
-
- template<typename Func>
- void BinaryInsertSort( int *pSortDest, int *pSortSrc, size_t nSort, Func compare )
- {
- if( pSortDest == NULL || pSortSrc == NULL || nSort == 0 )
- {
- return;
- }
- size_t nDone = 0;
- while( nSort )
- {
- int& nNext = pSortSrc[ nDone ];
- size_t L = 0;
- size_t begin=0;
- size_t end=nDone;
- size_t middle = (begin+end)/2;
-
- for(;;){
- if( compare(nNext, pSortDest[ middle ] ) )
- {
- end=middle;
- }
- else
- {
- begin=middle;
- }
- middle=(begin+end)/2;
- if(middle==begin)break;
- if(middle==end)break;
- }
- L=end;
-
-
- for( size_t move = nDone; move > L ; --move )
- {
- pSortDest[ move ] = pSortDest[ move - 1 ];
- }
- pSortDest[ L ] = nNext;
- --nSort;
- ++nDone;
- }
- }
-
- int main(void){
- int ToSort[]={8,3,2,7,6,1,5};
- bubleSort(ToSort,7,less<int>());
- copy(ToSort,ToSort+7,ostream_iterator<int>(cout,","));
- cout<<endl;
-
- int src[]={8,3,2,7,6};
- int dest[5];
- InsertSort(dest,src,5,less<int>());
- copy(dest,dest+5,ostream_iterator<int>(cout,","));
- cout<<endl;
-
- int src2[]={3,2,4};
- int dest2[3];
- BinaryInsertSort(dest2,src2,3,less<int>());
- copy(dest2,dest2+3,ostream_iterator<int>(cout,","));
-
- return 0;
- }