5.24 基础题目

 

快速幂

#include<bits/stdc++.h>
using namespace std;
//126348976 982638476 938420413
int main(){
    int a,b,p;
    cin>>a>>b>>p;
    long long res = 1,ci=1;
    int flag=0;
    if(b==0){
            res%=p;
        }
    else{
        while(b){
    	if (flag==0)ci=a%p;
    	else
          ci=(ci%p)*(ci%p)%p;
        
		if (b&1)res=(res*(ci%p))%p;
        b>>=1;
        flag++;
        //cout<<ci<<"  "<<res<<endl;
    }
    }
    cout<<res<<endl;
    return 0;
}

64位整数乘法

#include<bits/stdc++.h>
/*
a*b=a+a+a+...+a
a*1=a
a*2=2a
a*4=4a;
...
a*(2^k)=2^k*a;
*/
using namespace std;
typedef long long LL;
int main(){
    LL a,b,p;
    cin>>a>>b>>p;
    LL res=0;
    while(b){
        if(b&1)res=(res+a)%p;
        b>>=1;
        a=a*2%p;
    }
    cout<<res<<endl;
    return 0;
}

最短Hamilton路径

1s约计算1亿次;

 f[state][j]=

f[state_k][j]+weight[k][j];

state_k是state除去j之后的集合,state_k要包含k,k是state_k二进制表示中为1的下标,枚举出k

state_k=state-2^j;

for (int j = 0;j < 点数;j++){//n点数

        if ((state_k>>j )& 1 == 0)

          {    

                state=state_k+2^j;

                f[state][j]=f[state_k][j]+weight[k][j];

          }

}

 

#include <bits/stdc++.h>

using namespace std;
const int N=20,M=1<<20; 
int n;
int f[M][N],weight[N][N];
int main(){
	cin>>n;
	for(int i = 0;i < n;i++)
		for(int j = 0;j < n;j++){
			cin>>weight[i][j];
		}
		
	memset(f,0x3f,sizeof(f));
	f[1][0]=0;
	for(int i = 0;i < 1<<n;i++)//枚举所有的状态 
		for(int j = 0;j < n;j++){//枚举状态i二进制表示中所有的1的位置 
			if(i>>j & 1)
				for(int k = 0;k < n;k++)//枚举状态i去掉第j位后的剩余的1的位置 
					if(i-(1<<j) >> k & 1)//第k位是1 
						f[i][j]=min(f[i][j],f[i-(1<<j)][k]+weight[k][j]);
		}
	cout<<f[(1<<n)-1][n-1]<<endl;
	return 0;
}

汉诺塔问题(三塔)

#include <bits/stdc++.h>
using namespace std;
//f(x)=2^x-1
int hnt(int st,int mid,int dst,int n){
	if(n==1){
		//cout<<"from "<<char(st)<<" through "<<char(mid)<<" to "<<char(dst)<<" with "<<n<<endl;
		return 1;
	}
	else {
		int sum=0;
		cout<<"from "<<char(st)<<" through "<<char(dst)<<" to "<<char(mid)<<" with "<<n-1<<endl;
		sum+=hnt(st,dst,mid,n-1);
		cout<<"from "<<char(st)<<" through "<<char(mid)<<" to "<<char(dst)<<" with "<<1<<endl;
		sum+=hnt(st,mid,dst,1);
		cout<<"from "<<char(mid)<<" through "<<char(st)<<" to "<<char(dst)<<" with "<<n-1<<endl;
		sum+=hnt(mid,st,dst,n-1);
		return sum;
	}
}
int main(){
	int st,mid,dst,n;
	st=int('A'),mid=int('B'),dst=int('C');
	n=12;
	int ans = hnt(st,mid,dst,n);
	cout<<ans;
	return 0;
} 



四塔汉诺塔问题

// 凡是用到min的都需要,赋较大值。
    // memset以字节形式重置(int: 0x3f3f3f3f)
    //又0x3f的2倍为最大整数,所以还可以满足加法不越界

#include<bits/stdc++.h>

using namespace std;
const int N=15;
int d[N],f[N];
int main(){
    d[1]=1;
    for(int i = 2;i <=12;i++ )
    d[i]=d[i-1]+1+d[i-1];
    memset(f,0x3f,sizeof(f));
    f[0]=0;
    f[1]=1;
    //先让i个盘到B塔或者C塔,剩下的n-i盘在3塔情况下移到D
//再将i盘在4塔(因为D塔都是更重的盘)情况下移动到D。因为对于i我们不知道哪个最优,因此
//因此推导为 f[n] = min(f[n],2*f[i]+d[n-i])(for i in [1..n-1])
	for(int i =2;i <= 12;i++)
		for(int j = 1;j < i;j++)
			f[i]=min(f[i],f[j]+d[i-j]+f[j]);
	for(int i =1;i <= 12;i++)
		cout<<f[i]<<endl;
    
    
    return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值