蓝桥杯必备知识操作

全排列

模板写法

#include <iostream>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<queue>
#include<stack>
#include<cstring>
using namespace std;
int num[10],visit[10];
void fun(){
	for(int i=1;i<=9;i++){
		cout<<num[i]<<" ";
	}
	cout<<endl;
}
void dfs(int k){
	if(k==10){//表明已生成一个全排列 
		fun();//根据题目实现函数功能
		return ; 
	}
	for(int i=1;i<=9;i++){
		if(!visit[i]){
			num[k]=i;
			visit[i]=1;
			dfs(k+1);
			visit[i]=0;
		}		
	}
}

int main(){
	dfs(1);//生成 1到 9的全排列 
}

例题;
凑算式

A+B/C+DEF/GHI=10

(如果显示有问题,可以参见【图1.jpg】)

这个算式中A ~ I代表1 ~ 9的数字,不同的字母代表不同的数字。

比如:
6+8/3+952/714 就是一种解法,
5+3/1+972/486 是另一种解法。

这个算式一共有多少种解法?

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

代码

#include <iostream>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<queue>
#include<stack>
#include<cstring>
using namespace std;
int num[10],visit[10],ans;
void slove(){
	int B=num[2],C=num[3],DEF=num[4]*100+num[5]*10+num[6],GHI=num[7]*100+num[8]*10+num[9];
	if((B*GHI+DEF*C)%(C*GHI)!=0){
		return;
	}
	int k=(B*GHI+DEF*C)/(C*GHI);
	if (num[1]+k==10) ans++;
}
void dfs(int index)
{
	if(index == 10)//已经生成一个全排列 退出 
	{
		slove();
		return ;
	}
	for(int i = 1 ; i < 10 ; i ++)
	{
		if(!visit[i])
		{
			visit[i] = true;
			num[index] = i;
			dfs(index+1);
			visit[i] = false;//回溯 
		}
	}
}

int main(){
	dfs(1);
	cout<<ans;
  return 0;
}




//  freopen("testdata.in", "r", stdin);

使用next_permutation函数

#include <iostream>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<queue>
#include<stack>
#include<cstring>
using namespace std;
int num[10],visit[10],ans;
void slove(){
	int B=num[2],C=num[3],DEF=num[4]*100+num[5]*10+num[6],GHI=num[7]*100+num[8]*10+num[9];
	if((B*GHI+DEF*C)%(C*GHI)!=0){
		return;
	}
	int k=(B*GHI+DEF*C)/(C*GHI);
	if (num[1]+k==10) ans++;
}
int main(){
	for(int i=1;i<=9;i++){
		num[i]=i;
	}
	while(next_permutation(num+1,num+10)){
		slove();
	}
	cout<<ans;
  return 0;
}




//  freopen("testdata.in", "r", stdin);


判断闰年

闰年知识:公历年份是4的倍数的,且不是100的倍数,为普通闰年 公历年份是整百数的,必须是400的倍数才是世纪闰年

int fun(int x){
	return x%400==0 || (x%4==0 && x%100!=0);
}

判断素数

1.筛素数 时间复杂度比较高 但是比较好写

int isp(int x){
	if(x<=1) return 0;
	if(x==2) return 1;
	for(int i=2;i<=sqrt(x);i++){
		if(x%i==0) return 0;
	}
	return 1;
}

2.线性筛法 时间复杂度O(N)
例题洛谷P3383

#include<cstdio>
#include<iostream>
using namespace std;
int check[100000001];
int prime[1000001];
int main()
{
	int n,q;
	int cnt=0;
	//根据n<=10^8,q<=10^6开对应的数组大小,防止MLE
	//初始将check数组全部标记为0,标0的是素数,标1的不是素数
	scanf("%d%d",&n,&q);
	check[1]=1;//1不是素数
	for(int i=2;i<=n;i++)
	{
		if(!check[i])prime[cnt++]=i;//若当前数i没有被之前的所有数筛掉,表明i是素数,将i添加进素数表prime
		for(int j=0;j<cnt&&i*prime[j]<100000001;j++)//注意i*prime[j]不要超过n的上限(10^8)
		{
			check[i*prime[j]]=1;//将当前素数prime[j]的i倍标记为合数
			if(i%prime[j]==0)break;//关键步骤:保证每个合数只被筛一次
		}
	}
	for(int i=1;i<=q;i++)
	{
		scanf("%d",&n);
		printf("%d\n",prime[n-1]);//由于素数表从0开始存,所以输出时下标应减1
	}
	return 0;
}

int string 互相转换

利用stringstream实现功能

int转string
例题

/*
有些人很迷信数字,比如带“4”的数字,认为和“死”谐音,就觉得不吉利。
虽然这些说法纯属无稽之谈,但有时还要迎合大众的需求。某抽奖活动的奖券号码是5位数(10000-99999),要求其中不要出现带“4”的号码,主办单位请你计算一下,如果任何两张奖券不重号,最多可发出奖券多少张。
*/
#include <iostream>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<queue>
#include<stack>
#include<cstring>
#include<sstream>
using namespace std;
void i2s(int i,string &str){//str记得是引用
	stringstream ss;
	ss<<i;
	ss>>str;
}
int ans;
int main(){
	for(int i=10000;i<=99999;i++){
		string s;
		i2s(i,s);//将生成的数字转化成字符串类型
		if(s.find('4')==s.npos) ans++;
	}
	cout<<ans;
  return 0;
}


字符串转数字 同理反过来写即可

#include <iostream>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<queue>
#include<stack>
#include<cstring>
#include<sstream>
using namespace std;
void fun(int &x,string str){
	stringstream ss;
	ss<<str;
	ss>>x;
}
int main(){
	string s="12345";
	int x;
	fun(x,s);
	cout<<x;
  return 0;
}

经典日期问题

/*高斯出生于:1777年4月30日。

在高斯发现的一个重要定理的日记上标注着:5343,因此可算出那天是:1791年12月15日。

高斯获得博士学位的那天日记上标着:8113

请你算出高斯获得博士学位的年月日。

提交答案的格式是:yyyy-mm-dd, 例如:1980-03-21

请严格按照格式,通过浏览器提交答案。*/
#include <iostream>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<queue>
#include<stack>
#include<cstring>
using namespace std;
//1 3 5 7 8 10 12
//2 
//4 6 9 11
int fun(int x){
	return x%400==0 || (x%4==0 &&x%100!=0);
}
int main(){
	int y=1777;
	int m=4;
	int d=30;
	for(int i=1;i<=8112;i++){
		d++;
		if(m==12&&d==32){
			y++;
			m=1;
			d=1;
			continue;
		}
		if((m==1 || m==3 || m==5 || m==7 || m==8 || m==10)&&d==32){
			m++;
			d=1;
			continue;
		}
		if((m==4 || m==6 || m==9 || m==11)&&d==31){
			m++;
			d=1;
			continue;
		}
		if(m==2&&fun(y)&&d==30){
			m++;
			d=1;
			continue;
		}
		if(m==2&&!fun(y)&&d==29){
			m++;
			d=1;
			continue;
		}
	}
	printf("%04d-%02d-%02d\n",y,m,d);
  return 0;
}




//  freopen("testdata.in", "r", stdin);

分解质因数

void divide(int x)
{
    for (int i = 2; i <= x / i; i ++ )
        if (x % i == 0)
        {
            int s = 0;
            while (x % i == 0) x /= i, s ++ ;
            cout << i << ' ' << s << endl;
        }
    if (x > 1) cout << x << ' ' << 1 << endl;
    cout << endl;
}

欧几里得算法

int gcd(int a, int b)
{
    if(b==0){
    	return a;
	}
	else return gcd(b,a%b);
}

欧拉函数

欧拉函数是小于或等于n的正整数中与n互质的数的数目

int phi(int x)
{
    int res = x;
    for (int i = 2; i <= x / i; i ++ )
        if (x % i == 0)
        {
            res = res / i * (i - 1);
            while (x % i == 0) x /= i;
        }
    if (x > 1) res = res / x * (x - 1);

    return res;
}
posted @ 2020-10-11 14:54  一个经常掉线的人  阅读(244)  评论(0编辑  收藏  举报