2021.5.22 2022蓝桥杯练习赛3
Posted 斗奋力努
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2021.5.22 2022蓝桥杯练习赛3相关的知识,希望对你有一定的参考价值。
2021.5.22 2022蓝桥杯练习赛3
闲话:
1、就难度而言,本次练习赛题目整体比较简单,要是认真补了前两场的题,应该可以轻松做完4到5题。
2、就体验而言,这场练习赛数据普遍交弱,基本上瞎搞都能过。
3、遇到不会的多问,CCSU_MI大佬,CCSU_JPanel大佬。
4、本次做题过程十分快乐。
题目
1、试题 算法训练 矩阵加法
解析:对应位置相加可以了,学了线代的都知道,没学的也知道。
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n,m;
cin>>n>>m;
int a[n+5][m+5],b[n+5][m+5],c[n+5][m+5];
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
cin>>a[i][j];
}
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
cin>>b[i][j];
c[i][j]=a[i][j]+b[i][j];
}
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
cout<<c[i][j]<<" ";
}
cout<<endl;
}
}
----------------------------------------------------------------------------------------------------------------------------
2、试题 算法训练 删除多余括号
----------------------------------------------------------------------------------------------------------------------------
CCSU–JPanel大佬教我的硬模拟
#include<bits/stdc++.h>
#define x first
#define y second
using namespace std;
typedef pair<char,int>PLL;
string s;
bool vis[300];
stack<PLL>st;
char f(int x,int y){
bool flag=true;
for(int i=x+1;i<=y;i++){
if(vis[i]==0){
if(s[i]=='+'||s[i]=='-'){
if(flag) return s[i];
}
if(s[i]=='(') flag=false;
if(s[i]==')') flag=true;
}
}
return ' ';
}
int main(){
cin>>s;
for(int i=0;i<s.length();i++){
if(s[i]=='('){
if(i==0) st.push({' ',i});
else{
if(s[i-1]!='('&&s[i-1]!=')') st.push({s[i-1],i});
else st.push({' ',i});
}
}
if(s[i]==')'){
if(i!=s.length()-1){
PLL t=st.top();
char x=f(t.y,i);
if(x=='+'||x=='-'){
if(t.x=='*'||t.x=='/'||s[i+1]=='*'||s[i+1]=='/'){
st.pop();
}
else{
if(t.x=='-'&&x=='+'){
st.pop();
}
else{
st.pop();
vis[t.y]=vis[i]=1;
}
}
}
else{
st.pop();
vis[t.y]=vis[i]=1;
}
}
else{
PLL t=st.top();
char x=f(t.y,i);
if(x=='+'||x=='-'){
if(t.x=='*'||t.x=='/'){
st.pop();
}
else{
if(t.x=='-'&&x=='+'){
st.pop();
}
else{
st.pop();
vis[t.y]=vis[i]=1;
}
}
}
else{
st.pop();
vis[t.y]=vis[i]=1;
}
}
}
}
for(int i=0;i<s.length();i++){
if(!vis[i]) cout<<s[i];
}
}
----------------------------------------------------------------------------------------------------------------------------
3、试题 算法训练 邮票
解析:蓝桥杯数据很水,直接无脑dfs就可以了。
思路:
1、dfs(int p,int ne,int sum) 第1个参数表示位置,第2个参数表示已经贴了几张邮票,第3个参数表示当前总和(表示的数)。每次使vis[当前总和]=1
2、本题蓝桥后台数据最大数据为20,10,当n<27都可直接dfs水过。数据过大请看第二段代码。
----------------------------------------------------------------------------------------------------------------------------
#include<bits/stdc++.h>
using namespace std;
int n,m;
int a[300];
bool vis[30000];
void dfs(int p,int ne,int sum){
if(ne>n||p>m) return;
vis[sum]=1;
dfs(p+1,ne,sum);
dfs(p,ne+1,sum+a[p]);
}
int main(){
cin>>n>>m;
for(int i=1;i<=m;i++){
cin>>a[i];
vis[a[i]]=1;
}
dfs(1,0,0);
for(int i=1;i<=26000;i++){
if(!vis[i]){
cout<<i-1<<"\\n";
return 0;
}
}
}
----------------------------------------------------------------------------------------------------------------------------
CCSU__MI大佬的代码
#include<bits/stdc++.h>
using namespace std;
const int maxn = 25500 + 10;
vector<int>v;
int n, m;
int a[150];
int dp[maxn];
int main()
{
scanf("%d%d", &n, &m);
for (int i = 1; i <= m; i++)
{
scanf("%d", &a[i]);
dp[a[i]] = 1;
}
sort(a + 1, a + 1 + m);
for (int i = 1; i <= n * a[m]; i++)
{
if (dp[i] == 1)
{
v.push_back(i);
continue;
}
else
{
int minn = INT_MAX-10;
for (int j = 0; j < v.size(); j++)
minn = min(minn, dp[i-v[j]]);
if (minn + 1 > n)
{
printf("%d\\n", i - 1);
break;
}
dp[i] = minn + 1;
}
}
}
----------------------------------------------------------------------------------------------------------------------------
4、试题 算法提高 贪吃的大嘴
解析:这个题之前应该已经讲过了,就是一个背包问题,直接套背包模板就行。
#include<bits/stdc++.h>
using namespace std;
int n,m;
int a[55],b[55],dp[20005];
bool vis[20005];
int main(){
cin>>n>>m;
memset(dp,0x3f3f3f3f,sizeof(dp));
dp[0]=0;
for(int i=1;i<=m;i++) cin>>a[i]>>b[i];
for(int i=1;i<=m;i++){
for(int j=0;j<b[i];j++){
for(int k=n;k>=a[i];k--){
dp[k]=min(dp[k],dp[k-a[i]]+1);
}
}
}
if(dp[n]==0x3f3f3f3f) cout<<"><"<<"\\n";
else cout<<dp[n]<<"\\n";
}
----------------------------------------------------------------------------------------------------------------------------
5、试题 算法提高 超级玛丽
解析:裸的线性dp,没任何坑点
思路:
1、在vis数组中讲陷阱位置对应下标变成1。vis[i]=0代表位置i是空地,vis[i]=1代表位置i是陷阱。
2、因为超级玛丽无法连着跳2个单位长度,所以开始for循环一次vis数组,看看有没有连在一块的陷阱。
3、没有连在一块的陷阱。那么就开始dp。
其中dp[1]=1;
转移方程:
if(vis[i]==0) dp[i]=dp[i-1]+dp[i-2]。//第i个位置是空地
if(vis[i]==1) dp[i]=0; //第i个位置是陷阱
#include<bits/stdc++.h>
using namespace std;
int n,m;
bool vis[45];
int dp[45];
int main(){
cin>>n>>m;
for(int i=1;i<=m;i++){
int x; cin>>x;
vis[x]=1;
}
bool flag=0;
for(int i=2;i<n;i++){
if(vis[i]==1){
if(flag==1){
cout<<"0"<<"\\n";
return 0;
}
else{
flag=1;
}
}
else flag=0;
}
dp[1]=1;
for(int i=2;i<=n;i++){
if(vis[i]==1) dp[i]=0;
else dp[i]=dp[i-1]+dp[i-2];
}
cout<<dp[n]<<"\\n";
}
----------------------------------------------------------------------------------------------------------------------------
6、试题 算法提高 8皇后·改
解析:在经典8皇后问题上,将原来要求输出的路径改成了输出最大数字和
学习链接:八皇后问题详解(四种解法)
思路:
1、一种是将最后输出路径代码改成求值。最后sort排序输出最大值。(代码1)
2、一种是每次完成一种情况,每次max取值,然后最后输出最大值。(代码2)
----------------------------------------------------------------------------------------------------------------------------
代码1
#include<bits/stdc++.h>
using namespace std;
int ans[10],sum[100],t=0;
int a[10][10];
bool row[10],line1[20],line2[20];
void print()
{
for(int i=1;i<=8;i++)
{
sum[t]+=a[i][ans[i]];
}
t++;
}
void f(int step)
{
for(int i=1;i<=8;i++)
{
if(row[i]==false&&line1[step+i]==false&&line2[step+8-i]==false)
{
ans[step]=i;
if(step==8)
{
print();
}
row[i]=true;
line1[step+i]=true;
line2[step+8-i]=true;
f(step+1);
row[i]=false;
line1[step+i]=false;
line2[step+8-i]=false;
}
}
}
int main()
{
for(int i=1;i<=8;i++2021.5.29 2022蓝桥杯练习赛4