基本算法
基本算法
1.欧里几德算法求最大公约数(辗转相除法)
include<bits/stdc++.h>
using namespace std;
int a,b,c;//求a,b的最大公约数
int main()
{
cin>>a>>b;//可以直接使用__gcd(a,b)求出a,b的最大公约数
while(b>0)
{
c=a%b;
a=b;
b=c;
}
cout<<a;
} 2.筛选法求素数
#include<bits/stdc++.h>
using namespace std;
int n,a[100010];//筛选法求出1,n之间的所有素数
int main()
{
cin>>n;
for(int i=0;i<n;i++) a[i]=1;
a[0]=a[1]=0;
for(int i=2;i<=n;i++)
{
if(a[i]==1)
{
for(int j=i*2;j<=n;j+=i) a[j]=0;
}
}
for(int i=0;i<=n;i++)
{
if(a[i]==1) cout<<i<<" ";
}
return 0;
} 3.康托展开
//给出一个1~n的全排列中的某一个,求它是按字典序排列的第几个。
#include<bits/stdc++.h>
using namespace std;
int n,t,ans,vis[21],p[21]={1,1};
int main()
{
for(int i=2;i<=20;i++) p[i]=p[i-1]*i;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>t;
vis[t]=1;
int k=0;
for(int j=1;j<t;j++)
{
if(vis[j]==0) k++;
}
ans+=k*p[n-i];
}
cout<<ans+1<<endl;
return 0;
} 4.逆康托展开
int fac[] = {1,1,2,6,24,120,720,5040,40320};
//康托展开的逆运算,{1...n}的全排列,中的第k个数为s[]
void reverse_kangtuo(int n,int k,char s[])
{
int i, j, t, vst[8]={0};
--k;
for (i=0; i<n; i++)
{
t = k/fac[n-i-1];
for (j=1; j<=n; j++)
if (!vst[j])
{
if (t == 0) break;
--t;
}
s[i] = '0'+j;
vst[j] = 1;
k %= fac[n-i-1];
}
} 5.同余定理
1)a≡a(mod d) 2)a≡b(mod d)→b≡a(mod d) 3)(a≡b(mod d),b≡c(mod d))→a≡c(mod d) 如果a≡x(mod d),b≡m(mod d),则 4)a+b≡x+m (mod d) 5)a-b≡x-m (mod d) 6)a*b≡x*m (mod d ) 7)当d为素数时 若ab≡0 mod(d) 则有 a or b≡0 mod(d)
6.次方求模
1)将幂拆解为多个底数的平方次的积;
2)如果指数为偶数,把指数除以2,并让底数的平方次取余 ;
3)如果指数为奇数,就把多出来的底数记录下来,再执行偶数次操作。
int PowerMod(int a,int b,int c)//a的b次方对c取模
{
int ans=1;
a=a%c;
while(b>0)
{
if(b%2==1) ans=(ans*a)%c;
b=b/2;
a=(a*a)%c;
}
ans%=c;
return ans;
} 7.三角形面积
//海伦公式(注意S和p都用double)
//三角形三边为a,b,c,p=1.0/2*(a+b+c)[半周长],S为面积
//S=sqrt(p*(p-a)*(p-b)*(p-c))
#include<bits/stdc++.h>
using namespace std;
int a,b,c;
double p,S;
int main()
{
cin>>a>>b>>c;
p=(a+b+c)/2.0;
S=sqrt(p*(p-a)*(p-b)*(p-c));
cout<<S<<endl;
return 0;
} 8.三点顺序(顺时针or逆时针)
//利用矢量叉积右手定理
//1.四指指向a向量方向(右手垂直于平面)
//2.四指朝向b向量弯曲(注意弯曲方向的夹角要小于180°)
//3.大拇指指向为a*b的方向
//即叉积向上>0为逆时针,向下<0为顺时针
#include<bits/stdc++.h>
using namespace std;
int x1,y1,x2,y2,x3,y3;
int main()
{
while(cin>>x1>>y1>>x2>>y2>>x3>>y3)
{
if(x1==0&&y1==0&&x2==0&&y2==0&&x3==0&&y3==0) break;
int A=x2-x1;
int B=y2-y1;
int C=x3-x1;
int D=y3-y1;
if(A*D-B*C>0) cout<<"逆时针"<<endl;
else cout<<"顺时针"<<endl;
}
return 0;
} 9.二分查找
//在a[]中查找key所在的位置
#include<bits/stdc++.h>
using namespace std;
int BinSearch(int a[],int len,int key)
{
int low=0;
int high=len-1;
int mid;
while(low<=high)
{
mid=(low+high)/2;
if(key==a[mid]) return mid;
else if(key>a[mid]) low=mid+1;
else high=mid-1;
}
return -1;
}
int main()
{
int key;
cin>>key;
int a[]={1,2,3,4,5,6,7,8,9,10,11};
int len=sizeof(a)/sizeof(a[0]);
int ans=BinSearch(a,len,key);
cout<<ans;
return 0;
} 10.冒泡排序
#include<bits/stdc++.h>
using namespace std;
void bubble_sort(int a[],int n)
{
for(int i=1;i<n;i++)
{
for(int j=0;j<n-i-1;j++)
if(a[j]>a[j+1])
{
int temp=a[j];
a[j]=a[j+1];
a[j+1]=temp;
}
}
}
int main()
{
int a[10];
for(int i=0;i<10;i++) cin>>a[i];
bubble_sort(a,10);
for(int i=0;i<10;i++) cout<<a[i]<<" ";
return 0;
} 11.插入排序
#include<bits/stdc++.h>
using namespace std;
void insert_sort(int a[],int n)
{
int i,j;
for(i=1;i<n;i++)
{
for(j=i-1;j>=0;j--)
if(a[i]>a[j]) break;
if(j!=i-1)
{
int temp=a[i];
for(int k=i-1;k>j;k--) a[k+1]=a[k];
a[j+1] =temp;
}
}
}
int main()
{
int a[10];
for(int i=0;i<10;i++) cin>>a[i];
insert_sort(a,10);
for(int i=0;i<10;i++) cout<<a[i]<<" ";
return 0;
} 