一些基础的算法。
最大公约数gcd
开挂法:__gcd(a,b);
STL大法好!!!(震耳欲聋)
int gcd(int a,int b) { if(b==0) return a; return gcd(b,a%b); }
|
最大公约数与最小公倍数的关系gcd(a,b)*lcm(a,b)=ab
素数判断
简单法
暴力超时见祖宗
bool pand(int x) { for(int i=2; i*i<=x; i++) if(x%i==0) return 0; return 1; }
|
筛法
<1>1>取最小的素数2,筛去它的所有倍数
<2>2>取未被筛最小的数(一定是素数),再筛去它的所有倍数
<3>3>重复<2>2>直至全部都是素数(取最小数只需到 sqrt(n) )
bool isprime[N] int n,ans=0; int main() { memset(isprime,1,sizeof(isprime)); cin>>n; isprime[1]=0; for(int i=2; i<=sqrt(n); i++) if(isprime[i]) for(int k=i*i; k<=n; k+=i) isprime[k]=0; for(int i=2; i<=n; i++) if(isprime[i]) {ans++; cout<<i<<" ";} cout<<endl<<ans<<endl; return 0; }
|
排序
选择排序
for(int i=1; i<=n-1; i++) for(int j=i+1; j<=n; j++) if(a[i]>a[j]) t=a[j],a[j]=a[i],a[i]=t;
|
冒泡排序
对于接近有序的数列,加标记可以缩短排序时间
for(int i=n-1; i>=1; i--){ int p=0; for(int k=1; k<=i; k++) if(d[k]>d[k+1]) swap(d[k+1],d[k]),p=1; if(!p) break; }
|
插入排序
for(int i=2; i<=n; i++){ int p=a[i]; for(int k=i; k>1 && p<a[k-1]; k--) a[k]=a[k-1]; a[k]=p; }
|
快排
sort(a+1,a+n+1,cmp);
STL大法好!!!(再次破音)
void sort(int l,int r) { int x=l,y=r,mid=a[(l+r)/2]; do{ while(a[i]<mid) x++; while(mid<a[y]) y--; if(x<=y) swap(a[x],a[y]),x++,y--; }while(x<=y); if(l<y) qsort(l,y); if(x<r) qsort(x,r); }
|
归并排序
把两个已经有序的序列,归并成一个有序的序列
归并排序不会像快排那样蜕化为o(n2),最好和最坏的情况都是o(nlog2n)
void merge_sort(int l,int r) { if(l!=r){ int mid=(l+r)/2; merge_sort(l,mid); merge_sort(mid+1,r); merge(l,mid,r); } }
|
void merge(int p,int q,int r) { int tt=p,tl=p,tr=q+1; while(tt<=r){ if(tl<=q && (tr>r || a[tl]<a[tr])) tmp[tt++]=a[tl++]; else tmp[tt++]=a[tr++]; } for(int i=p;i<=r;i++) a[i]=tmp[i]; }
|
二分
a[ ]已经排序
递归算法
bool find(int x,int l,int r) { if(l>r) return 0; int mid=(l+r)/2; if(x==a[mid]) return 1; if(x<a[mid]) return find(x,l,mid-1); if(x>a[mid]) return find(x,mid+1,r); }
|
非递归算法
bool find(int x,int l,int r) { while(l<=r){ int mid=(l+r)/2; if(x==mid) return 1; if(x<a[mid]) r=mid-1; else l=mid+1; } }
|
快速幂
ans=1,a%=p; while(b){ if(b%2==1) ans=(ans*a)%p; a=(a*a)%p; b>>1; } cout<<ans<<endl;
|