蓝桥杯必备知识操作
全排列
模板写法
#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;
}