🐾马上就要蓝桥杯了,最后的这几天尤为重要,不可懈怠哦🐾
1.饮料换购
-
题目
乐羊羊饮料厂正在举办一次促销优惠活动。乐羊羊 C 型饮料,凭 3 个瓶盖可以再换一瓶 C 型饮料,并且可以一直循环下去(但不允许暂借或赊账)。
请你计算一下,如果小明不浪费瓶盖,尽量地参加活动,那么,对于他初始买入的 n 瓶饮料,最后他一共能喝到多少瓶饮料。
输入描述
输入一个整数 n(0<n<1000),表示开始购买的饮料数量。
输出描述
输出一个整数,表示实际得到的饮料数
输入输出样例
示例
输入
100
输出
149
-
第一次 AC 60%
#include<bits/stdc++.h> using namespace std; int main() { int n; cin>>n; int sum=n; while(n>3) { sum+=n/3; n=n/3+n%3; } cout<<sum; return 0; }
-
第二次 AC 100%
#include<bits/stdc++.h> using namespace std; int main() { int n; cin>>n; int sum=n; while(n>=3) //这里认真考虑!!!! { int t=n/3; sum+=t; n=t+n%3; } cout<<sum; return 0; }
-
反思
简单题都不能一次 AC , 第一次,没有包含n==3
边界条件的重要性
2.受伤的皇后
-
题目
有一个 n×n 的国际象棋棋盘(n 行 n 列的方格图),请在棋盘中摆放 n 个受伤的国际象棋皇后,要求:
- 任何两个皇后不在同一行。
- 任何两个皇后不在同一列。
- 如果两个皇后在同一条 45 度角的斜线上,这两个皇后之间行号的差值至少为 3 。
请问一共有多少种摆放方案。
输入描述
输入的第一行包含一个整数 n。
其中,1≤n≤10。
输出描述
输出一个整数,表示答案。
输入输出样例
示例 1
输入
4
输出
2
-
第一次 AC 0%
#include<bits/stdc++.h> using namespace std; typedef pair<int,int> PII; const int N=20; int n; bool col[N],row[N],dg[N]; bool st[N][N]; int ans; //表示存的方案 bool check(int a,int b) //判断对角线上 是否满足条件 { int dx[8]={-2,-1,1,2,-2,-1,1,2}; int dy[8]={-2,-1,1,2,2,1,-1,-2}; for(int i=0;i<8;i++) { int x=a+dx[i],y=b+dy[i]; if(x>=0&&x<n&&y<n&&y>=0&&st[x][y]==1) //对角线上几个位置,只要有皇后就是返回0 return false; } return true; } void dfs(int u) { if(u==n+1) { ans++; return; } for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) //枚举每一行每一列 { if(!row[i]&&!col[j]&&check(i,j)) //判断 { row[i]=true; col[j]=true; st[i][j]=true; dfs(u+1); st[i][j]=0; col[j]=0; row[i]=0; } } } } int main() { cin>>n; dfs(1); cout<<ans; return 0; }
好久没与写过 dfs ,隐隐约约记得模板是这样的,样例都过不了,先去复习一下
-
第二次 AC 100%
#include<bits/stdc++.h> using namespace std; const int N=20; int n; bool col[N],row[N]; bool st[N][N]; int ans; //表示存的方案 bool check(int a,int b) //判断对角线上 是否满足条件 { int dx[8]={-2,-1,1,2,-2,-1,1,2}; int dy[8]={-2,-1,1,2,2,1,-1,-2}; for(int i=0;i<8;i++) { int x=a+dx[i],y=b+dy[i]; if(x>=0&&x<n&&y<n&&y>=0&&st[x][y]==1) //对角线上几个位置,只要有皇后就是返回0 return false; } return true; } void dfs(int x,int y,int u) { if(y==n) y=0,x++; if(x==n) { if(u==n) { ans++; } return ; //注意这里回溯的位置 } //遍历每一个点,每一个有两种情况 放,不放 //分支1 放皇后 if(!row[x]&&!col[y]&&check(x,y)&&!st[x][y]) { row[x]=col[y]=st[x][y]=1; dfs(x,y+1,u+1); row[x]=col[y]=st[x][y]=0; //回溯 } //分支2 不放皇后 dfs(x,y+1,u); } int main() { cin>>n; dfs(0,0,0); cout<<ans; return 0; }
-
骗分? AC 100%
#include <iostream> using namespace std; int main() { int n; cin>>n; cout<<2; return 0; }
一个样例直接过,咱就说蓝桥杯比赛的时候,会出现吗 qwq
-
反思
我使用的是遍历所有点,每个点分两种情况放和不放来处理的。
dfs 回溯+深搜+恢复现场
考试的时候,不会的题,一定要把样例写上去,骗分!!
3.超级质数
-
题目
如果一个质数 P 的每位数字都是质数, 而且每两个相邻的数字组成的两位 数是质数, 而且每三位相邻的数字组成的三位数是质数, 依次类推, 如果每相 邻的 k 位数字组成的 k 位数都是质数, 则 P 称为超级质数。
如果把超级质数 P 看成一个字符串, 则这个超级质数的每个子串都是质 数。
例如, 53 是一个超级质数。
请问, 最大的超级质数是多少?
答案提交
这是一道结果填空的题, 你只需要算出结果后提交即可。本题的结果为一 个整数, 在提交答案时只填写这个整数, 填写多余的内容将无法得分。
-
第一次
想要暴力枚举每一个数和它的每一位,每两位,但不知道咋实现,而且我推不出来范围
-
题解一
超级质数要求每位数都是质数,而个位的质数只有2,3,5,7因此两位数的超级质数有23,37,53,57,73… //三位数的有237…,373,377,533,577,537,,733…四位数的超级质数不存在(必定有2、5所以会出现两位非质数) //将4个数字组合成不同的三位数,除以6,看余数是否为1或5,再判断大小
推出来是 373
-
题解二 ——重点
#include<bits/stdc++.h> using namespace std; bool prime_number(int num) //判断素数 方法一 { if (num <= 3) return num > 1; if (num % 2 == 0) return false; if (num %6 != 1 && num % 6 != 5) return false; for (int i = 3; i < sqrt(num); i += 2) if (num % i == 0) return false; return true; } /*bool isprime(int x) //判断素数 方法二 { if(x<=1) return false; int sqr=(int) sqrt(1.0*x); for(int i=2;i<=sqr;i++) { if(x%i==0) return false; } return true; }*/ int main() { int max = 0; for (int k = 53; k < 1000; k ++) //求最大,从53开始循环即可 { int flag = 1; //标记 if (prime_number(k)) { string str = to_string(k); //数字转字符串 for (int i = 0; i < str.size(); i ++) { for (int j = 1; j <= str.size() - i; j ++) { string s = str.substr(i , j); //取子串 int n = stoi(s); //子串转数字 if ( !prime_number(n) ) //不是质数,跳出循环 { flag = 0; break; } } if (!flag) break; } if (flag) //是质数,赋值 max = k; } } cout << max << endl; return 0; }
-
知识补充
- s=to_string(n):数字转为字符串
- s=substr(i,j):复制子字符串,从指定位置开始并具有指定的长度,substr(start , length)
- n=stoi(s):字符串转为数字,stoi(字符串 , 起始位置 , n进制)
-
stoi(字符串,起始位置,
n
2~32进制),将n进制的字符串转化为十进制。#include<iostream> #include<cstdio> #include<string> using namespace std; int main() { string str = "1010"; int a = stoi(str, 0, 2); cout << a << endl; return 0; }
输出:10
将二进制的1010转化为十进制。
-
反思/收获
这个题解太赞了
质数就是素数,素数的判断方法又学到一种
取出一个字符串的全部子串的方法
for (int i = 0; i < str.size(); i ++) for (int j = 1; j <= str.size() - i; j ++) //注意这里的细节 1、!、= -i string s = str.substr(i , j);