winter week2 day1
2024 蓝桥杯模拟赛 2 (div1+div2)
A[传智杯 #4 初赛] 报告赋分
#include<bits/stdc++.h> using namespace std; #define int long long //#define int __int128 #define double long double typedef pair<int,int>PII; typedef pair<string,int>PSI; typedef pair<string,string>PSS; const int N=100+5,INF=0x3f3f3f3f,Mod=1e9+7,mod=998244353; const int MAXN=1e8+5; const double eps=1e-12; const int dx[4]={-1,1,0,0}; const int dy[4]={0,0,-1,1}; void solve() { int a,p; cin>>a>>p; if(p<16)a-=10; if(p>20)a-=p-20; a=max(0ll,a); cout<<a<<'\n'; } signed main(){ ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); int t=1; cin>>t; while(t--){ solve(); } return 0; }
B[传智杯 #3 初赛] 课程报名
#include<bits/stdc++.h> using namespace std; #define int long long //#define int __int128 #define double long double typedef pair<int,int>PII; typedef pair<string,int>PSI; typedef pair<string,string>PSS; const int N=100+5,INF=0x3f3f3f3f,Mod=1e9+7,mod=998244353; const int MAXN=1e8+5; const double eps=1e-12; const int dx[4]={-1,1,0,0}; const int dy[4]={0,0,-1,1}; void solve() { int n,v,m,a; cin>>n>>v>>m>>a; int ans=0; for(int i=1;i+m-1<=n;i+=m){ ans+=v*m; v+=a; } if(n%m)ans+=(n%m)*v; cout<<ans; } signed main(){ ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); int t=1; // cin>>t; while(t--){ solve(); } return 0; }
C[传智杯 #4 初赛] 小卡和质数
思路:要使最后一位异或为1说明两个数相邻,只存在一对相邻数满足为素数(相邻数奇偶不同,偶数只有2为素数),为2和3
#include<bits/stdc++.h> using namespace std; #define int long long //#define int __int128 #define double long double typedef pair<int,int>PII; typedef pair<string,int>PSI; typedef pair<string,string>PSS; const int N=100+5,INF=0x3f3f3f3f,Mod=1e9+7,mod=998244353; const int MAXN=1e8+5; const double eps=1e-12; const int dx[4]={-1,1,0,0}; const int dy[4]={0,0,-1,1}; void solve() { int x,y; cin>>x>>y; if(x>y)swap(x,y); if(x==1&&y==2)cout<<"Yes\n"; else cout<<"No\n"; } signed main(){ ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); int t=1; cin>>t; while(t--){ solve(); } return 0; }
D[蓝桥杯 2013 国 AC] 网络寻路
思路:找长度为3的路径,可以枚举中间的边,那么这条边的贡献是两端点所连边数(度数-1)的乘积
或者暴力跑dfs统计从所有点出发的可行路径
#include<bits/stdc++.h> using namespace std; #define int long long //#define int __int128 #define double long double typedef pair<int,int>PII; typedef pair<string,int>PSI; typedef pair<string,string>PSS; const int N=100+5,INF=0x3f3f3f3f,Mod=1e9+7,mod=998244353; const int MAXN=1e8+5; const double eps=1e-12; const int dx[4]={-1,1,0,0}; const int dy[4]={0,0,-1,1}; void solve() { int n,m; cin>>n>>m; vector<int>cnt(n+1); vector<PII>ve(m); for(int i=0;i<m;++i){ cin>>ve[i].first>>ve[i].second; cnt[ve[i].first]++,cnt[ve[i].second]++; } int ans=0; for(int i=0;i<m;++i){ ans+=2*(cnt[ve[i].second]-1)*(cnt[ve[i].first]-1); } cout<<ans; } signed main(){ ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); int t=1; // cin>>t; while(t--){ solve(); } return 0; }
E[蓝桥杯 2018 省 AB] 全球变暖
思路:bfs
#include<bits/stdc++.h> using namespace std; #define int long long //#define int __int128 #define double long double typedef pair<int,int>PII; typedef pair<string,int>PSI; typedef pair<string,string>PSS; const int N=100+5,INF=0x3f3f3f3f,Mod=1e9+7,mod=998244353; const int MAXN=1e8+5; const double eps=1e-12; const int dx[4]={-1,1,0,0}; const int dy[4]={0,0,-1,1}; void solve() { int n; cin>>n; string s[n+1],ss[n+1]; for(int i=1;i<=n;++i){ cin>>s[i]; s[i]=' '+s[i]; ss[i]=s[i]; } int idx=1; vector<vector<int>>ve(n+1,vector<int>(n+1)); auto bfs=[&](int x,int y,int now){ s[x][y]='.'; ve[x][y]=now; queue<PII>q; q.push({x,y}); while(q.size()){ auto t=q.front();q.pop(); for(int i=0;i<4;++i){ int xx=t.first+dx[i],yy=t.second+dy[i]; if(xx>=1&&xx<=n&&yy>=1&&yy<=n&&s[xx][yy]=='#'){ ve[xx][yy]=now; q.push({xx,yy}); s[xx][yy]='.'; } } } }; for(int i=1;i<=n;++i){ for(int j=1;j<=n;++j){ if(s[i][j]=='#'){ bfs(i,j,idx++); } } } // for(int i=1;i<=n;++i){ // for(int j=1;j<=n;++j)cout<<ve[i][j]; // cout<<'\n'; // } set<int>se; for(int i=1;i<=n;++i){ for(int j=1;j<=n;++j){ if(ss[i][j]!='#')continue; bool ok=true; for(int k=0;k<4;++k){ int xx=i+dx[k],yy=j+dy[k]; if(xx>=1&&xx<=n&&yy>=1&&yy<=n&&ss[xx][yy]=='.'){ ok=false; break; } } // if(i==1||i==n||j==1||j==n)ok=false; if(!ok)ve[i][j]=0; if(ve[i][j]!=0)se.insert(ve[i][j]); } } // for(auto v:se)cout<<v<<'\n';cout<<'\n'; cout<<idx-se.size()-1; } signed main(){ ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); int t=1; // cin>>t; while(t--){ solve(); } return 0; }
F[蓝桥杯 2022 国 B] 出差
思路:求最短路
#include<bits/stdc++.h> using namespace std; #define int long long //#define int __int128 #define double long double typedef pair<int,int>PII; typedef pair<string,int>PSI; typedef pair<string,string>PSS; const int N=100+5,INF=0x3f3f3f3f,Mod=1e9+7,mod=998244353; const int MAXN=1e8+5; const double eps=1e-12; const int dx[4]={-1,1,0,0}; const int dy[4]={0,0,-1,1}; void solve() { int n,m;cin>>n>>m; vector<int>t(n+1); for(int i=1;i<=n;++i)cin>>t[i]; t[1]=t[n]=0; vector<PII>ve[n+1]; for(int i=0;i<m;++i){ int u,v,c; cin>>u>>v>>c; ve[u].push_back({v,c+t[v]}); ve[v].push_back({u,c+t[u]}); } vector<int>dis(n+1,INF),st(n+1); dis[1]=0; priority_queue<PII,vector<PII>,greater<PII>>q; q.push({dis[1],1}); while(q.size()){ auto s=q.top(); q.pop(); if(st[s.second])continue; st[s.second]=1; for(auto v:ve[s.second]){ if(!st[v.first]&&dis[v.first]>dis[s.second]+v.second){ dis[v.first]=dis[s.second]+v.second; q.push({dis[v.first],v.first}); } } } cout<<dis[n]; } signed main(){ ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); int t=1; // cin>>t; while(t--){ solve(); } return 0; }
G[蓝桥杯 2022 国 B] 搬砖
思路:贪心排序+dp,直接dp肯定不行,有的砖摆放顺序可变。摆放顺序为i到1:从下到上,由于需满足vi>wi-1+...w1、vi-1>wi-2+...+w1,推出vi>wi-1+vi-1,按这样的关系对所有砖排序,然后就是求01背包了,记得限制条件为j<v[i]
#include<bits/stdc++.h> using namespace std; #define int long long //#define int __int128 #define double long double typedef pair<int,int>PII; typedef pair<string,int>PSI; typedef pair<string,string>PSS; const int N=100+5,INF=0x3f3f3f3f,Mod=1e9+7,mod=998244353; const int MAXN=1e8+5; const double eps=1e-12; const int dx[4]={-1,1,0,0}; const int dy[4]={0,0,-1,1}; struct E{ int w,v; bool operator<(const E&e)const{ if(e.v>w+v)return true; if(v>e.w+e.v)return false; if(w!=e.w)return w<e.w; return v<e.v; } }; void solve() { int n; cin>>n; int all=0; vector<E>ve(n+1); for(int i=1;i<=n;++i){ cin>>ve[i].w>>ve[i].v; all+=ve[i].w; } sort(ve.begin()+1,ve.end()); vector<vector<int>>f(n+1,vector<int>(all+1)); for(int i=1;i<=n;++i){ for(int j=0;j<=all;++j){ f[i][j]=max(f[i][j],f[i-1][j]); if(j<=ve[i].v&&j+ve[i].w<=all){ f[i][j+ve[i].w]=max(f[i][j+ve[i].w],f[i-1][j]+ve[i].v); } } } int ans=0; for(int i=0;i<=all;++i)ans=max(ans,f[n][i]); cout<<ans; } signed main(){ ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); int t=1; // cin>>t; while(t--){ solve(); } return 0; }
H[蓝桥杯 2014 省 AB] 地宫取宝
思路:dp,数据都不是很大,用四维数组f[i][j][k][s]表示到达(i,j)时取了k个宝贝且最大价值为s的方案。有两种情况:不拿和拿。
不拿:f[i][j][k][s]+=f[i-1][j][k][s]+f[i][j-1][k][s]
拿:f[i][j][k][c[i][j]]+=f[i-1][j][k-1][0~c[i][j]-1]+f[i][j-1][k-1][0~c[i][j]-1]
#include<bits/stdc++.h> using namespace std; #define int long long //#define int __int128 #define double long double typedef pair<int,int>PII; typedef pair<string,int>PSI; typedef pair<string,string>PSS; const int N=100+5,INF=0x3f3f3f3f,Mod=1e9+7,mod=998244353; const int MAXN=1e8+5; const double eps=1e-12; const int dx[4]={-1,1,0,0}; const int dy[4]={0,0,-1,1}; int f[55][55][15][15]; void solve() { int n,m,k;cin>>n>>m>>k; vector<vector<int>>ve(n+1,vector<int>(m+1)); int ma=0; for(int i=1;i<=n;++i){ for(int j=1;j<=m;++j){ cin>>ve[i][j]; ve[i][j]++; ma=max(ma,ve[i][j]); } } f[1][1][0][0]=f[1][1][1][ve[1][1]]=1; for(int i=1;i<=n;++i){ for(int j=1;j<=m;++j){ if(i==1&&j==1)continue; for(int kk=0;kk<=k;++kk){ for(int s=0;s<=13;++s){ f[i][j][kk][s]=(f[i][j][kk][s]+f[i-1][j][kk][s]+f[i][j-1][kk][s])%Mod; if(kk>0&&s<ve[i][j]){ f[i][j][kk][ve[i][j]]+=f[i-1][j][kk-1][s];f[i][j][kk][ve[i][j]]%=Mod; f[i][j][kk][ve[i][j]]+=f[i][j-1][kk-1][s];f[i][j][kk][ve[i][j]]%=Mod; } } // cout<<f[i][j][kk][ve[i][j]]<<'\n'; } } } int ans=0; for(int i=k;i<=ma;++i){ ans+=f[n][m][k][i]; ans%=Mod; } cout<<ans; } signed main(){ ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); int t=1; // cin>>t; while(t--){ solve(); } return 0; }
I[蓝桥杯 2022 省 A] 选数异或
思路:刚开始看成每个询问不同的x了,后面发现x是给定的阿,那就很好做了。要找到a^b=x,其实就是找a和x^b,那就对每个a找最近的x^b。边枚举a边用哈希表存之前出现的数的最近位置,找x^b时之前看哈希表里有没有即可。由于有多个问题,那就用前缀最大值预处理出边界r前最近的x^b的位置,每次询问判断找到的位置是否不小于l
#include<bits/stdc++.h> using namespace std; #define int long long //#define int __int128 #define double long double typedef pair<int,int>PII; typedef pair<string,int>PSI; typedef pair<string,string>PSS; const int N=100+5,INF=0x3f3f3f3f,Mod=1e9+7,mod=998244353; const int MAXN=1e8+5; const double eps=1e-12; const int dx[4]={-1,1,0,0}; const int dy[4]={0,0,-1,1}; void solve() { int n,m,x; cin>>n>>m>>x; vector<int>ve(n+1); map<int,int>mp; for(int i=1;i<=n;++i){ int s; cin>>s; mp[s]=i; if(mp.count(x^s))ve[i]=mp[x^s]; ve[i]=max(ve[i-1],ve[i]); } while(m--){ int l,r; cin>>l>>r; if(ve[r]<l)cout<<"no\n"; else cout<<"yes\n"; } } signed main(){ ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); int t=1; // cin>>t; while(t--){ solve(); } return 0; }