2023年第十四届蓝桥杯大赛软件类省赛Java大学B组真题
C.数组分割
思路:因为最后要是分为2组偶数。由于偶数+偶数=偶数,奇数+奇数=偶数。那么我们的奇数个数一定要是偶数个。如果奇数个数为奇数个那直接就不行了,答案是0。如果奇数的个数是偶数的话,假设偶数n个,奇数m个。
// AC one more times // nndbk #include <bits/stdc++.h> using namespace std; typedef long long ll; const int mod = 1e9 + 7; const int N = 2e5 + 10; ll qmi(ll a, ll b, ll mod) { ll ans = 1 % mod; while(b) { if(b & 1) ans = ans * a % mod; a = a * a % mod; b >>= 1; } return ans; } int main() { ios::sync_with_stdio(false); cin.tie(nullptr), cout.tie(nullptr); int t; cin>>t; while(t--) { int n; cin>>n; ll odd = 0,even = 0; for(int i = 1;i <= n; i++) { ll x; cin>>x; if(x % 2)odd++; else even++; } if(odd % 2)cout<<0<<"\n"; else{ ll ans = 1; if(odd) ans = qmi(2ll,odd-1,mod); ans %= mod; ans *= qmi(2ll,even,mod); ans %= mod; cout<<ans<<"\n"; } } return 0; }
D.矩形总面积
小模拟+容斥一下
对于重叠部分:
// AC one more times // nndbk #include <bits/stdc++.h> using namespace std; typedef long long ll; const int mod = 1e9 + 7; const int N = 2e5 + 10; int main() { ios::sync_with_stdio(false); cin.tie(nullptr), cout.tie(nullptr); ll x1,y1,x2,y2,x3,y3,x4,y4; cin>>x1>>y1>>x2>>y2>>x3>>y3>>x4>>y4; //(x1,y1) (x2,y2) (x3,y3) (x4,y4) ll s1 = (x2-x1)*(y2-y1); ll s2 = (x4-x3)*(y4-y3); ll sx = max(x1,x3),sy = max(y1,y3); ll ex = min(x2,x4),ey = min(y2,y4); if(sx < ex && sy < ey) cout<<s1+s2-(ex-sx)*(ey-sy)<<"\n"; else cout<<s1+s2<<"\n"; return 0; }
E.蜗牛
是一个
思路:定义状态
注意,一开始我们在
由于第一个到第二个是特殊的。我们需要把第二个也手动初始化。
为什么第二个是特殊的呢?因为第一个到第二个的传送不需要代价,而对于别的比如第二个到第三个,需要先爬到传送点。
考虑完特殊的,其他的就很简单啦。具体的见代码。
// AC one more times // nndbk #include <bits/stdc++.h> using namespace std; typedef long long ll; const int mod = 1e9 + 7; const int N = 2e5 + 10; int x[N]; struct node { int h1,h2; }a[N]; double dp[N][2]; int main() { //ios::sync_with_stdio(false); cin.tie(nullptr), cout.tie(nullptr); int n; cin>>n; for(int i = 1;i <= n; i++) cin>>x[i]; //up 0.7 ,down 1.3 //第i个的h1高度传送门到达i+1的h2高度 for(int i = 1;i < n; i++) cin>>a[i].h1>>a[i].h2; dp[1][0] = x[1],dp[1][1] = x[1]+a[1].h1/0.7; dp[2][0] = min(dp[1][0]+(x[2]-x[1]),dp[1][1]+a[1].h1/1.3+(x[2]-x[1])); dp[2][1] = min(dp[1][0]+a[1].h1/0.7,dp[1][1]); for(int i = 3;i <= n; i++) { dp[i][0] = min(dp[i-1][0]+(x[i]-x[i-1]),dp[i-1][1]+(a[i-2].h2)/1.3+(x[i]-x[i-1])); if(a[i-2].h2 < a[i-1].h1) dp[i][1] =dp[i-1][1]+(a[i-1].h1-a[i-2].h2)/0.7; else dp[i][1] = dp[i-1][1]+(a[i-2].h2-a[i-1].h1)/1.3; dp[i][1] = min(dp[i][1],dp[i-1][0]+a[i-1].h1/0.7); } printf("%.2lf",min(dp[n][0],dp[n][1]+a[n-1].h2/1.3)); return 0; }
F.合并区域
啊这个我一开始想简单了,以为只有一个地方可以进行合并,但发现可以有多个....写起来很恶心,要不断建图,然后dfs
G.买二赠一
贪心+单调队列
先排序,从大到小的买。当买了两个,较小的那个的价格的一半放入单调队列。每次买之前check一下能否使用免费,能用就用。
// AC one more times // nndbk #include <bits/stdc++.h> using namespace std; typedef long long ll; const int mod = 1e9 + 7; const int N = 5e5 + 10; int a[N]; bool cmp(int a,int b) { return a > b; } int main() { ios::sync_with_stdio(false); cin.tie(nullptr), cout.tie(nullptr); int n; cin>>n; for(int i = 1;i <= n; i++) cin>>a[i]; sort(a+1,a+1+n,cmp); int l = 1; ll ans = 0; priority_queue<int>q; auto check_can_free = [&](){ while(!q.empty() && l <= n) { int t = q.top(); if(t >= a[l]){ q.pop(); l++; }else break; } }; while(l <= n) { check_can_free(); if(l<=n) { ans += a[l]; l++; } check_can_free(); if(l<=n) { ans += a[l]; q.push(a[l]/2); l++; } } cout<<ans<<"\n"; return 0; }
I.最大开支
挺经典的一个题目,对于这类题,我们考虑,对于某一个项目,如果x个人参加价格就是
我们对二者做差就是
我们用priority_queue来实现(自定义排序),每次把增量最大的取出来,如果增量
自定义排序模板:
struct cmp{ bool operator()(vector<int>&a,vector<int>&b){ return a[0]>b[0]; } }; priority_queue<vector<int>,vector<vector<int>>,cmp> q;//小顶堆
代码:
// AC one more times // nndbk #include <bits/stdc++.h> using namespace std; typedef long long ll; const int mod = 1e9 + 7; const int N = 2e5 + 10; ll get(ll x,ll k,ll b) { return x*max(0ll,k*x+b); } ll add(int x,int k,int b) { //return get(x+1,k,b)-get(x,k,b); return 2ll*k*x+k+b; } struct Node { int num,k,b; Node(int _num,int _k,int _b){num = _num;k = _k;b = _b;}; }; struct cmp{ bool operator()(Node& a,Node& b){ ll cost1 = get(a.num+1,a.k,a.b)-get(a.num,a.k,a.b); ll cost2 = get(b.num+1,b.k,b.b)-get(b.num,b.k,b.b); return cost1 < cost2; } }; priority_queue<Node,vector<Node>,cmp> q; int main() { ios::sync_with_stdio(false); cin.tie(nullptr), cout.tie(nullptr); int n,m; cin>>n>>m; for(int i = 1;i <= m; i++) { ll k,b; cin>>k>>b; q.push(Node(0ll,k,b)); } //max(0,kx+b) //need = x*(kx+b) = kx^2 + bx //mx = -(b/2*k) or -(b/k*k+1) //(k*(x+1)+b)*(x+1)-(kx+b)*x //2kx+k+b for(int i = 1;i <= n; i++) { Node t = q.top(); q.pop(); int num = t.num,k = t.k,b = t.b; ll cost = add(num,k,b); //cout<<"num = "<<num<<"k = "<<k<<" b = "<<b<<" cost = "<<cost<<"\n"; if(cost<=0) { q.push(t); break; }else{ t.num++; q.push(t); } } ll ans = 0; while(!q.empty()) { Node t = q.top(); q.pop(); int num = t.num,k = t.k,b = t.b; ans += get(num,k,b); } cout<<ans<<"\n"; return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix