【学术】20道经典题代码汇总

【目录】

  1. 高精度加法
  2. 高精度减法
  3. 高精度乘法
  4. 高精度除以整型
  5. 高精度除法
  6. 并查集
  7. 树状数组(子区间的和)
  8. 快速幂取模
  9. 埃氏筛法
  10. 欧拉函数
  11. 哈希+宽搜(八数码问题)
  12. 全排列
  13. 有重复元素的全排列
  14. n的全排列
  15. 求n的r组合
  16. 汉诺塔问题
  17. 八皇后
  18. 自然数的拆分
  19. 手打快排
  20. 逆元
  21. 欧拉筛法
  22. 最短路减半问题

(未完待续)


【正文】

1.高精度加法

#include<bits/stdc++.h>
using namespace std;
string ra,rb;
int lena,lenb;
int a[1001],b[1001],ans[1001];
int main(){
	cin>>ra;
	cin>>rb;
	lena=ra.size();
	lenb=rb.size();
	for(int i=lena;i>=1;i--){
		a[i]=(int)(ra[lena-i]-'0');
	}
	for(int i=lenb;i>=1;i--){
		b[i]=(int)(rb[lenb-i]-'0');
	}
	int len=max(lena,lenb);
	for(int i=1;i<=len;i++){
		ans[i]+=a[i]+b[i];
		ans[i+1]=(ans[i]/10);
		ans[i]%=10;
	}
	if(ans[len+1]){
		len++;
	}
	for(int i=len;i>=1;i--){
		printf("%d",ans[i]);
	}
}

2.高精度减法

#include<bits/stdc++.h>
using namespace std;
char ra[301],rb[301],t[301];
int lena,lenb,len;
int a[1001],b[1001],ans[1001];
int main(){
	cin>>ra;
	cin>>rb;
	lena=strlen(ra);
	lenb=strlen(rb);
	len=max(lena,lenb);
	if(lena<lenb||lena==lenb&&strcmp(ra,rb)<0){
		printf("-");
		strcpy(t,ra);
		strcpy(ra,rb);
		strcpy(rb,t);
		swap(lena,lenb);
	}
	for(int i=lena;i>=1;i--){
		a[i]=(int)(ra[lena-i]-'0');
	}
	for(int i=lenb;i>=1;i--){
		b[i]=(int)(rb[lenb-i]-'0');
	}
	/*for(int i=1;i<=lena;i++){
		printf("%d",a[i]);
	}
	cout<<endl;
	for(int i=1;i<=lenb;i++){
		printf("%d",b[i]);
	}*/ 
	for(int i=1;i<=len;i++){
		if(a[i]-b[i]<0){
			a[i]+=10;
			a[i+1]--;
		}
		ans[i]=a[i]-b[i];
	}
	bool flag=true;
	for(int i=len;i>=1;i--){
		if(ans[i]!=0){
			flag=false;
		}
		if(!flag){
			printf("%d",ans[i]);
		}
	}
	if(flag){
		printf("0");
	}
}

3.高精度乘法

#include<bits/stdc++.h>
using namespace std;
char ra[301],rb[301];
int a[301],b[301],c[1001];
int lena,lenb;
int main(){
	cin>>ra;
	cin>>rb;
	lena=strlen(ra);
	lenb=strlen(rb);
	for(int i=lena;i>=1;i--){
		a[i]=(int)(ra[lena-i]-'0');
	}
	for(int i=lenb;i>=1;i--){
		b[i]=(int)(rb[lenb-i]-'0');
	}
	int len=lena+lenb-1;
	for(int i=1;i<=lena;i++){
		for(int j=1;j<=lenb;j++){
			c[i+j-1]+=(a[i]*b[j]);
			c[i+j]+=(c[i+j-1]/10);
			c[i+j-1]%=10;
		}
	}
	while(c[len+1]){len++;}
	for(int i=len;i>=1;i--){
		printf("%d",c[i]);
	}
}

4.高精度除以整型

#include <bits/stdc++.h>
using namespace std;
int len, a[1001], b, c[1001];
char ra[1001];
int main() {
    cin >> ra;
    scanf("%d", &b);
    int x = 0;
    len = strlen(ra);
    for (int i = len; i >= 1; i--) {
        a[i] = ra[len - i] - '0';
    }
    for (int i = len; i >= 1; i--) {
        c[i] = (x * 10 + a[i]) / b;
        x = (x * 10 + a[i]) % b;
    }
    while (len > 0 && c[len] == 0) {
        len--;
    }
    for (int i = len; i >= 1; i--) {
        printf("%d", c[i]);
    }
    if (len == 0)
        printf("0");
    cout << endl << x;
}

5.高精度除法

#include<bits/stdc++.h>
using namespace std;
char ra[1001],rb[1001];
int a[1001],b[1001],c[1001],t[1001];
int cmp(int a[],int b[]){
    if(a[0]>b[0]){
    	return 1;
	}
    if(a[0]<b[0]){
    	return -1;
	}
    for(int i=a[0];i>=1;i--){
        if(a[i]>b[i]){
        	return 1;
		}
        if(a[i]<b[i]){
        	return -1;
		}
    }
    return 0;
}
void sub(int a[],int b[]){
	int f=cmp(a,b);
	if(f==0){
		a[0]=0;
	}
	if(f==1){
		for(int i=1;i<=a[0];i++){
			if(a[i]<b[i]){
				a[i+1]--;
				a[i]+=10;
			}
			a[i]-=b[i];
		}
		while(a[0]>0&&a[a[0]]==0){
			a[0]--;
		}
	}
}
int main(){
	cin>>ra;
	cin>>rb;
	a[0]=strlen(ra);
	b[0]=strlen(rb);
	c[0]=a[0]-b[0]+1;
	for(int i=1;i<=a[0];i++){
		a[i]=ra[a[0]-i]-'0';
	}
	for(int i=1;i<=b[0];i++){
		b[i]=rb[b[0]-i]-'0';
	}
	for(int i=c[0];i>=1;i--){
		memset(t,0,sizeof(t));
		t[0]=b[0]+i-1;
		for(int j=1;j<=b[0];j++){
			t[i+j-1]=b[j];
		}
		while(cmp(a,t)>=0){
			c[i]++;
			sub(a,t);
		}
	}
	while(c[0]>0&&c[c[0]]==0){
		c[0]--;
	}
	if(c[0]==0){
		printf("0");
	}else{
		for(int i=c[0];i>=1;i--){
			printf("%d",c[i]);
		}
	}
	printf("\n");
	if(a[0]==0){
		printf("0");
	}else{
		for(int i=a[0];i>=1;i--){
			printf("%d",a[i]);
		}
	}
}

6.并查集

#include<bits/stdc++.h>
using namespace std;
int n,m,z,x,y,p[10001];
int f(int x){
	if(x==p[x]){
		return x;
	}else{
		return p[x]=f(p[x]);
	}
}
int main(){
	cin>>n>>m;
	for(int i=1;i<=n;i++)p[i]=i;
	for(int i=1;i<=m;i++){
		cin>>z>>x>>y;
		if(z==1){
			p[f(y)]=f(x);
		}else{
			if(f(p[x])==f(p[y])){
				cout<<"Y"<<endl;
			}else{
				cout<<"N"<<endl;
			}
		}
	}
}

7.树状数组(子区间的和)

#include<bits/stdc++.h>
using namespace std;
long long n,m,a[200001],tree[200001];
long long lowbit(long long x){
    return x&-x;
}
long long sum(long long x){
	long long sum=0;
	while(x){
		sum+=tree[x];
		x-=lowbit(x);
	}
	return sum;
}
void update(long long x,long long y){
	while(x<=200000){
		tree[x]+=y;
		x+=lowbit(x);
	}
}
int main(){
	scanf("%lld",&n);
	for(int i=1;i<=n;i++){
		scanf("%lld",&a[i]);
		update(i,a[i]);
	}
	char ch;
	int x,y;
	cin>>ch;
	while(ch!='Q'){
		if(ch=='P'){
			scanf("%d%d",&x,&y);
			printf("%d\n",sum(y)-sum(x-1));
		}else if(ch=='-'){
			scanf("%d%d",&x,&y);
			update(x,-y);
		}else if(ch=='+'){
			scanf("%d%d",&x,&y);
			update(x,y);
		}
		cin>>ch;
	}
}

8.快速幂取模

#include<bits/stdc++.h>
using namespace std;
#define LL long long
LL n,m,mn;
LL ksm(LL a,LL b){
	int r;
	for(r=1;b;b>>=1,a=a*a%mn){
		if(b&1){
			r=r*a%mn;
		}
	}
	return r;
}
int main(){
	cin>>n>>m>>mn;
	cout<<ksm(n,m)%mn;
}

9.埃氏筛法

#include<bits/stdc++.h>
using namespace std;
bool is_prime[10000001];
int main(){
	int n;
	scanf("%d",&n);
	memset(is_prime,true,sizeof(is_prime));
	is_prime[0]=is_prime[1]=false;
	for(int i=2;i<=n;i++){
		if(is_prime[i]){
			for(int j=2;j*i<=n;j++){
				is_prime[i*j]=false; 
			}
		}
	}
	for(int i=1;i<n;i++){
		if(is_prime[i]){
			printf("%d\n",i);
		}
	}
}

10.欧拉函数

#include<bits/stdc++.h>
using namespace std;
int eular(int n){
    int ans=n;
    for(int i=2;i*i<=n;++i){
        if(n%i==0){
            ans=ans/i*(i-1);
            while(n%i==0)n/=i;
        }
    }
    if(n>1)ans=ans/n*(n-1);
    return ans;
}
int main(){
	int n;
	scanf("%d",&n);
	printf("%d",eular(n));
}

11.哈希+宽搜(八数码问题)

#include<cstdio>
#include<iostream>
using namespace std;
int ans[4][4],q[1000001][4][4],h[1000001],a[4][4];
int dx[5]={0,0,0,-1,1},dy[5]={0,-1,1,0,0};
int p[1000001];
int t=0,w=1;
int temp;
const int m=1000003;
bool flag=false;
int hash1(int x){
	int y=(x-1)%m+1;
	while(h[y]!=0&&h[y]!=x){
		y++;
		if(y>m)y=1;
	}
	return y;
}
bool check(){
	for(int i=1;i<=3;i++){
		for(int j=1;j<=3;j++){
			if(q[t][i][j]!=ans[i][j]){
				return false;
			}
		}
	}
	return true;
}
void bfs(){
	while(t<w){
		t++;
		if(check()){
			printf("%d",p[t]);
			flag=1;
			return ;
		}
		int x,y;
		for(int i=1;i<=3;i++){
			for(int j=1;j<=3;j++){
				if(q[t][i][j]==0){
					x=i;
					y=j;
					break;
				}
			}
		}
		for(int i=1;i<=4;i++){
			int xx=dx[i]+x,yy=dy[i]+y;
			if(xx>=1&&xx<=3&&yy>=1&&yy<=3){
				w++;
				for(int j=1;j<=3;j++){
					for(int k=1;k<=3;k++){
						q[w][j][k]=q[t][j][k];
					}
				}
				q[w][xx][yy]=q[t][x][y];
				q[w][x][y]=q[t][xx][yy];
				p[w]=p[t]+1;
				temp=0;
				for(int j=1;j<=3;j++){
					for(int k=1;k<=3;k++){
						temp=temp*10+q[w][j][k];
					}
				}
				if(h[hash1(temp)]==0){
					h[hash1(temp)]=temp;
				}else{
					w--;
				}
			}
		}
	}
}
int main(){
	for(int i=1;i<=3;i++){
		for(int j=1;j<=3;j++){
			scanf("%d",&q[w][i][j]);
			temp=temp*10+q[w][i][j];
		}
	}
	h[hash1(temp)]=1; 
	for(int i=1;i<=3;i++){
		for(int j=1;j<=3;j++){
			scanf("%d",&ans[i][j]);
		}
	}
	bfs();
	if(!flag){
		printf("-1");
	}
	return 0;
}

12.全排列

#include<bits/stdc++.h>
using namespace std;
char a[10];
char b[10];
int n;
int vis[10];
void dfs(int x){
   if(x==n) {
       b[x]='\0';
       printf("%s\n",b);
   }
   for(int i=0;i<n;i++)
       if(vis[i]==0){
           vis[i]=1;			 
           b[x]=a[i];
           dfs(x+1);
           vis[i]=0;
       }
}
int main() {
   scanf("%s",a);
   n=strlen(a);
   dfs(0);
   return 0;
}

13.有重复元素的全排列

#include<bits/stdc++.h>
using namespace std;
char a[101],b[101];
int n,sum,s[1001];
int dfs(int x){
	if(x>n){
		sum++;
		cout<<sum<<":";
		for(int i=1;i<=n;i++){
			printf("%c",b[i]); 
		}
		printf("\n");
	}else{
		for(int i=97;i<=123;i++){
			if(s[i]){
				b[x]=(char)i;
				s[i]--;
				dfs(x+1);
				s[i]++;
			}
		}
	}
}
int main(){
	scanf("%s",a);
	n=strlen(a);
	for(int i=0;i<n;i++){
		s[(int)a[i]]++;
	}
	dfs(1);
}

14.n的全排列

#include<bits/stdc++.h>
using namespace std;
int ans[11];
bool vis[11];
int len;
void f(int x){
	if(x==len){
		for(int i=0;i<len;i++){
			printf("%d",ans[i]);
		}
		printf("\n"); 
		return ;
	}else{
		for(int i=0;i<len;i++){
			if(!vis[i]){
				vis[i]=1;
				ans[x]=i+1;
				f(x+1);
				vis[i]=0;
			}
		}
	}
} 
int main(){ 
	scanf("%d",&len);
	f(0);
}

15.求n的r组合

#include<bits/stdc++.h>
using namespace std;
int n,r,ans[1001],cnt;
bool vis[1001];
void dfs1(int x,int y){
	if(y==0){
		cnt++;
		return;
	}
	for(int i=y;i<=x;i++){
		dfs1(i-1,y-1);
	}
}
void dfs(int x){
	if(x>r){
		for(int i=1;i<=r;i++){
			printf("%d ",ans[i]);
		}
		printf("\n");
		return ;
	}else{
		for(int i=1;i<=n;i++){
			if(!vis[i]&&ans[x-1]<i){
				ans[x]=i;
				vis[i]=1;
				dfs(x+1);
				vis[i]=0;
			}
		}
	}
}
int main(){
	scanf("%d%d",&n,&r);
	dfs1(n,r);
	cout<<cnt<<endl;
	dfs(1);
}

16.汉诺塔问题

#include<bits/stdc++.h>
using namespace std;
int n;
void dfs(int x,int a,int b,int c){
	if(x==0){
		return ;
	}else{
		dfs(x-1,a,c,b);
		printf("%c->%d->%c\n",a,x,b);
		dfs(x-1,c,b,a);
	}
}
int main(){
	char a,b,c;
	scanf("%d %c %c %c",&n,&a,&b,&c);
	dfs(n,a,b,c);
}

17.八皇后

#include<iostream>
#include<cstdio>
using namespace std;
int n=8,tot,m,g;
int a[14],b[14],c[30],d[30];
void sear(int x){
    if(x==n+1){
    tot++;         
    if(tot==g){
        for(int i=1;i<=n;i++)
        	cout<<a[i];
        cout<<endl; 
    }
    return ;
    }
    for(int i=1;i<=n;i++)
    if(!b[i]&&!c[x+i]&&!d[x-i+n]){
        a[x]=i;
        b[i]=1;
        c[x+i]=1;
        d[x-i+n]=1;
        sear(x+1);
        b[i]=0;
        c[x+i]=0;
        d[x-i+n]=0;
    }
}
int main(){
    cin>>m;
	for(int i=1;i<=m;i++){
		cin>>g;
		tot=0;
		sear(1);
	}
    return 0;
}

18.自然数的拆分

#include <bits/stdc++.h>
using namespace std;
int n, ans[31];
void dfs(int x,int y) {
    if(x==0){
    	for(int i=1;i<y-1;i++){
    		printf("%d+",ans[i]);
		}
		printf("%d\n",ans[y-1]);
		return ;
	}
	for(int i=1;i<n;i++){
		if(x-i>=0&&i>=ans[y-1]){
			ans[y]=i;
			dfs(x-i,y+1);
			ans[y]=0;
		}
	}
}
int main() {
    scanf("%d", &n);
    dfs(n,1);
}

19.手打快排

#include<stdio.h>

int a[1000],n,q;;

void qs(int a[],int l,int r)

{

if(l>=r) return;

int mid=(l+r)/2,i=l,j=r;

while(i<=j)

{

	while(a[i]<a[mid]&&i<j) i++;//看看有没有那个数比基准数大的(左边)

	while(a[j]>a[mid]&&i<j) j--;//看看有没有那个数比基准数小的(右边)

	if(i<=j)

	{//交换

		int t=a[i];

		a[i]=a[j];

		a[j]=t;

		i++;j--;//继续

	}

}

qs(a,l,mid);//递归搜左边的

qs(a,mid+1,r);//递归搜右边的
}

int main()

{ scanf("%d%d",&n,&q);

for(int i=1;i<=n;i++)

	scanf("%d",&a[i]);

qs(a,1,n);

for(int i=1;i<=n;i++)

{

	printf("%d ",a[i]);

}

return 0;
}

20.逆元

#include<bits/stdc++.h>
using namespace std;
long long x,y;
int oula(int x)
{
    int ans=x;
    for(int i=2;i*i<=x;i++){
        if(x%i==0){
            ans=ans/i*(i-1);
            while(x%i==0){
                x/=i;
            }
        }
    }
    if(x>1){
        ans=ans-ans/x;
    }
    return ans;
}//~~显然,~~欧拉函数
long long ksm(long long a,long long b)
{
    long long r=1;
    while(b)
    {
        if(b&1)
        {
            r=(r*a)%y;
        }
        b>>=1;
        a=a*a%y;
    }
    return r%y;
}//~~显然,~~快速幂
int main()
{
    cin>>x>>y;
    cout<<ksm(x,oula(y)-1);
    return 0;
}//~~显然,主程序~~

21.欧拉筛法

#include<bits/stdc++.h>
using namespace std;
#define MAXN 10000005
int n,vis[MAXN],pri[MAXN],cnt=0;
int main()
{
	scanf("%d",&n);
	for(int i=2;i<n;i++)
	{
		if(!vis[i]) pri[++cnt]=i;
		for(int j=1;j<=cnt && i*pri[j]<=n;j++)
		{
			vis[i*pri[j]]=1;
			if(i%pri[j]==0) break;
		}
	}
	for(int i=1;i<=cnt;i++) printf("%d\n",pri[i]);
	return 0;
}

22.最短路减半问题

#include <bits/stdc++.h>
using namespace std;
int n, m, x, y, z, t, h[10005], dis[2][10005], last[2][10005];
struct road {
    int to, s, next;
} a[20005];
queue<int> q;
void add(int x, int y, int z) {
    t++;
    a[t].to = y;
    a[t].s = z;
    a[t].next = h[x];
    h[x] = t;
}

int main() {
    cin >> n >> m;
    for (int i = 1; i <= m; i++) {
        cin >> x >> y >> z;
        add(x, y, z);
        add(y, x, z);
    }
    for (int i = 2; i <= n; i++) dis[1][i] = 1e9, dis[0][i] = 1e9, last[0][i] = 1e9, last[1][i] = 1e9;
    q.push(1);
    while (!q.empty()) {
        int x = q.front();
        q.pop();
        for (int i = h[x]; i; i = a[i].next) {
            int y = a[i].to;
            int z = a[i].s;
            if (dis[0][y] > dis[0][x] + z) {
                dis[0][y] = dis[0][x] + z;
                q.push(y);
            }
            if (dis[1][y] >= dis[0][x] + z / 2) {
                dis[1][y] = dis[0][x] + z / 2;
                last[0][y] = x;
                last[1][y] = y;
                q.push(y);
            }
            if (dis[1][y] >= dis[1][x] + z) {
                last[0][y] = last[0][x];
                last[1][y] = last[1][x];
                dis[1][y] = dis[1][x] + z;
                q.push(y);
            }
        }
    }
    cout << last[0][n] << ' ' << last[1][n] << endl;
    cout << dis[1][n] << endl;
}
posted @ 2022-03-25 20:11  zswangziye  阅读(49)  评论(0编辑  收藏  举报