作者:指针不指南吗
专栏:蓝桥杯倒计时冲刺马上就要蓝桥杯了,最后的这几天尤为重要,不可懈怠哦
题目
链接: 饮料换购 - 蓝桥云课 (lanqiao.cn)
乐羊羊饮料厂正在举办一次促销优惠活动。乐羊羊 C 型饮料,凭 3 个瓶盖可以再换一瓶 C 型饮料,并且可以一直循环下去(但不允许暂借或赊账)。
请你计算一下,如果小明不浪费瓶盖,尽量地参加活动,那么,对于他初始买入的 n 瓶饮料,最后他一共能喝到多少瓶饮料。
输入描述
输入一个整数 n(0<n<1000),表示开始购买的饮料数量。
输出描述
输出一个整数,表示实际得到的饮料数
输入输出样例
示例
输入
100
输出
149
第一次 AC 60%
#include
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
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
边界条件的重要性
题目
链接: 受伤的皇后 - 蓝桥云课 (lanqiao.cn)
有一个 n×n 的国际象棋棋盘(n 行 n 列的方格图),请在棋盘中摆放 n 个受伤的国际象棋皇后,要求:
- 任何两个皇后不在同一行。
- 任何两个皇后不在同一列。
- 如果两个皇后在同一条 45 度角的斜线上,这两个皇后之间行号的差值至少为 3 。
请问一共有多少种摆放方案。
输入描述
输入的第一行包含一个整数 n。
其中,1≤n≤10。
输出描述
输出一个整数,表示答案。
输入输出样例
示例 1
输入
4
输出
2
第一次 AC 0%
#include
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
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
using namespace std;
int main()
{
int n;
cin>>n;
cout<<2;
return 0;
}
反思
我使用的是遍历所有点,每个点分两种情况放和不放来处理的。
dfs 回溯+深搜+恢复现场
考试的时候,不会的题,一定要把样例写上去,骗分!!
题目
链接: 超级质数 - 蓝桥云课 (lanqiao.cn)
如果一个质数 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
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;
}
知识补充
stoi(字符串,起始位置,n
2~32进制),将n进制的字符串转化为十进制。
#include
#include
#include
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);