蓝桥杯常用代码模板总结(C/C++)

蓝桥杯常用代码模板总结(C/C++)
1.排序
(1)冒泡排序
C++代码:

void BubbleSort(int a[], int n)  
{  
    for (int i = 0; i < n - 1; i++)  
    {  
            for (int j = 0; j < n - i - 1; j++)  
            {  
                    if (a[j] > a[j + 1])   
            {  
                            int t = a[j];  
                            a[j] = a[j + 1];  
                            a[j + 1] = t;  
                        }  
                 }  
         }  
}  

2.快速幂运算

long pow_2(int b)
{  
	long  x = 2 ;  
	long  res = 1 ;   
	while ( b > 0 )
	{  
		if ( b & 1 )  
		res *= x;  
		b >>= 1;//右移一位  
		x = x * x ;  
	}  
	return  res;  
}  

注:这里所求的是2的幂运算(代码原理就不详细讲解了~),如果要求解其他幂次方,可作如下修改:

long  pow_2 ( int a,int  b )
{  
	long  x = a ;  
........
}

3.最大公约数

int  gcd  (  long  a  ,  long  b  )
{
	return  b==0?a:gcd(b,a%b);
}

4.进制转换问题
(1)使用setbase(n)函数
在C++中提供setbase(n)进制转换函数,支持八进制、十进制以及十六进制之间的相互转换,举例格式如下:

cout<<setbase(n)<<x<<endl;

注:

  • 将x转换为n进制输出
  • 需要加入的头文件:
#include<iostream>
#include<iomanip>

代码示例:将十六进制转换为八进制输出
输入:输入的第一行为一个正整数n (1<=n<=10);
接下来n行,每行一个由0-9、大写字母A~F组成的字符串,表示要转换的十六进制正整数
输出:输出n行,每行为输入对应的八进制正整数

#include<iostream>
#include <iomanip>
using namespace std;
 int main()
 {
 	int n,x,i;
 	cin>>n;
 	int a[n];
 	
 	for(int i=0;i<n;i++)
 	{
 		cin>>hex>>x;
 		a[i]=x;	
 	}
 	for(int i=0;i<n;i++)
 	{
 		cout<<setbase(8)<<a[i]<<endl;
 	}
 return 0;
 }

运行结果:
运行结果图
5.判断素数

/* 判断素数 */
bool isPrime(LL n) {
	for (int i = 2; i * i <= n; ++i)
		if (n % i == 0)
			return false;
	return true;
}

6.全排列总结
全排列也是蓝桥杯中常考的题型,全排列的实现方法有多种,模板代码如下:
(1)采用递归方法

void f(int k)
{
	if(k==13)//这个判断条件由题目决定,这里指有13个需要全排列的数
	{
		if(check())//check()函数需要根据题目要求编写
		ans++;
	}
	for(int i=k;i<13;++i)
	{//递归
		int t=a[i];
		a[i]=a[k];
		a[k]=t;
			f(k+1);
	{//回溯
		int t=a[i];
		a[i]=a[k];
		a[k]=t;
	}
	}
}

(2)采用next_permutation函数
首先需要添加头文件

#include<algorithm>

代码模板:

int main(int argc,const char *argv[])
{
	do{
		if(check())
		ans++;
	}while(next_permutation(a,a+13));
	cout<<ans<<endl;
	return 0;
}

next_permutation(数组头地址,数组尾地址);若下一个排列存在,则返回真,如果不存在则返回假;若求上一个排列,则用prev_permutation。
(3)这可以算是对第一种方法的简化

void f(int k,int path[12])
{
	if(k==13)
	{
		if(check(path))
		ans++;
	}
	for(int i=0;i<13;++i)
	{
		if(i>0&&a[i]==a[i-1]&&!vis[i-1]) continue;
		
		if(!vis[i]){//没有被用过的元素可以抓入到path
			vis[i]=true;//标记为已访问
			path[k]=a[i];//被a[i]填入到path[k]中
			f(k+1,path);//递归
			vis[i]=false;//回溯
		}
	}

}

举个栗子~

现在小学的数学题目也不是那么好玩的。
看看这个寒假作业:

   □ + □ = □
   □ - □ = □
   □ × □ = □
   □ ÷ □ = □
   
每个方块代表1~13中的某一个数字,但不能重复。
比如:
 6  + 7 = 13
 9  - 8 = 1
 3  * 4 = 12
 10 / 2 = 5

以及:
 7  + 6 = 13
 9  - 8 = 1
 3  * 4 = 12
 10 / 2 = 5

就算两种解法。(加法,乘法交换律后算不同的方案)
 
你一共找到了多少种方案?

请填写表示方案数目的整数。
注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。

方法一:

#include<iostream>
#include<cstdio>
using namespace std;
int a[]={1,2,3,4,5,6,7,8,9,10,11,12,13};
int ans=0;
bool check()
{
	if(a[0]+a[1]==a[2]&&
	a[3]-a[4]==a[5]&&
	a[6]*a[7]==a[8]&&
	a[9]%a[10]==0&&
	a[9]/a[10]==a[11])
	return true;
	return false;
}
void f(int k)
{
	if(k==13)
	{
		if(check())
		ans++;
	}
	for(int i=k;i<13;++i)
	{
		int t=a[i];
		a[i]=a[k];
		a[k]=t;
			f(k+1);
	{
		int t=a[i];
		a[i]=a[k];
		a[k]=t;
	}
	}

}
int main(int argc,const char *argv[])
{
	f(0);
	cout<<ans<<endl;
	return 0;
}

方法二:

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int a[]={1,2,3,4,5,6,7,8,9,10,11,12,13};
int ans=0;
bool check()
{
	if(a[0]+a[1]==a[2]&&
	a[3]-a[4]==a[5]&&
	a[6]*a[7]==a[8]&&
	a[9]%a[10]==0&&
	a[9]/a[10]==a[11])
	return true;
	return false;
}
int main(int argc,const char *argv[])
{
	do{
		if(check())
		ans++;
	}while(next_permutation(a,a+13));
	cout<<ans<<endl;
	return 0;
}

方法三:

#include<iostream>
#include<cstdio>
using namespace std;
int a[]={1,2,3,4,5,6,7,8,9,10,11,12,13};
int ans=0;
int path[13];
bool vis[13];
bool check(int path[12])
{
	if(a[0]+a[1]==a[2]&&
	a[3]-a[4]==a[5]&&
	a[6]*a[7]==a[8]&&
	a[9]%a[10]==0&&
	a[9]/a[10]==a[11])
	return true;
	return false;
}

void f(int k,int path[12])
{
	if(k==13)
	{
		if(check(path))
		ans++;
	}
	for(int i=0;i<13;++i)
	{
		if(i>0&&a[i]==a[i-1]&&!vis[i-1]) continue;
		
		if(!vis[i]){
			vis[i]=true;
			path[k]=a[i];
			f(k+1,path);
			vis[i]=false;
		}
	}

}
int main(int argc,const char *argv[])
{
	f(0,path);
	cout<<ans<<endl;
	return 0;
}

7.优先队列
定义:

priority_queue<Type, Container, Functional>

Type:数据类型;
Container:容器类型,必须是用数组实现的容器,比如vector,deque等等,但不能用 list,一般默认为vector;
Functional:比较的方式。
自定义数据类型时需要传入三个参数,使用基本数据类型时,只需要传入数据类型,默认为大顶堆(降序)。
举例:

//升序
priority_queue <int,vector<int>,greater<int> > q;
//降序
priority_queue <int,vector<int>,less<int> >q;
//注意>>之间一定要有空格,否则会成为右移运算符

例题:
标题:第几个幸运数

到x星球旅行的游客都被发给一个整数,作为游客编号。
x星的国王有个怪癖,他只喜欢数字3,5和7。
国王规定,游客的编号如果只含有因子:3,5,7,就可以获得一份奖品。

我们来看前10个幸运数字是:
3 5 7 9 15 21 25 27 35 45
因而第11个幸运数字是:49

小明领到了一个幸运数字 59084709587505,他去领奖的时候,人家要求他准确地说出这是第几个幸运数字,否则领不到奖品。

请你帮小明计算一下,59084709587505是第几个幸运数字。

需要提交的是一个整数,请不要填写任何多余内容。
#include<bits/stdc++.h>
using namespace std;
const int a[]={3,5,7};
const long long maxn=59084709587505;
priority_queue<long long,vector<long long>,greater<long long> > p;
set<long long>s;
int res;
int main()
{
	long long n,m;
	for(int i=0;i<3;i++)
	p.push(a[i]);
	while((n=p.top())<=maxn){
		p.pop();
		res++;
		for(int i=0;i<3;i++){
			m=n*a[i];
			if(!s.count(m)){
				s.insert(m);
				p.push(m);
			}
			
		}
	}
	cout<<res<<endl;
	return 0;
}
//参考链接:
//原文链接:https://blog.youkuaiyun.com/krypton12138/article/details/79801924

(更新中…)

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

橘子味的小橙

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值