csp-s真题题解
csp题目讲解
csp-s 2021
P7913 [CSP-S 2021] 廊桥分配
时隔3个月我都以为忘没了,口胡了发现是一样的思路,非常厉害啊,那就不管了放个口胡解法得了。
latex我也不改了就这样吧。
依次处理国内部和国际部,将飞机按抵达时间排序,ans[i]存第i个机场库能存放的飞机,处理国内部,一个飞机着落了,如果没有任何飞机,直接降落机场库,ans[1]++,如果有飞机那就叠一层,ans[2]++,再加入一个,发现第一个离开了,此时是ans[1]++,再来一个但没有飞机起飞,ans[3]++,以此类推,然后国际部也这么做,统计答案时候,for(int i=1;i<=k;i++)ans[i]+=ans[i-1]是为了统计,最后for(int i=0;i<=n;i++) mx=max(mx,ans1[i]-ans2[n-i],然后输出mx,感觉非常可行
#include <bits/stdc++.h> using namespace std; const int N=1e6+10; #define pi pair<int,int> int n,m1,m2; struct ss{ int l,r; }a[N],b[N]; int ans1[N],ans2[N]; bool cmp(ss g,ss h){ return g.l<h.l; } void solve(ss *s,int t,int *ans){ priority_queue<pi,vector<pi>,greater<pi> > q; priority_queue<int,vector<int>,greater<int> > p; for(int i=1;i<=n;i++){ p.push(i); } for(int i=1;i<=t;i++){ while(!q.empty()&&q.top().first<=s[i].l){ p.push(q.top().second); q.pop(); } if(p.empty()){ continue; } int k=p.top(); p.pop(); ans[k]++; q.push({s[i].r,k}); } for(int i=1;i<=n;i++){ ans[i]+=ans[i-1]; } } signed main(){ ios::sync_with_stdio(false); cin.tie(nullptr); cin>>n>>m1>>m2; for(int i=1;i<=m1;i++){ cin>>a[i].l>>a[i].r; } for(int i=1;i<=m2;i++){ cin>>b[i].l>>b[i].r; } sort(a+1,a+m1+1,cmp); sort(b+1,b+m2+1,cmp); solve(a,m1,ans1); solve(b,m2,ans2); int mx=0; for(int i=0;i<=n;i++){ mx=max(mx,ans1[i]+ans2[n-i]); } cout<<mx; return 0; }
P7915 [CSP-S 2021] 回文
在算法实现上可以去大佬里看,我只会口胡下并写下点小细节。
因为是2n个数必定有重复,画一下图发现回文序列的末尾一定是原数列中间的连续的区间,此时我们就可以枚举这个中间的区间来判断是否合法,而且从后向前选区间一定是最小字典序,因为这样右边的数就更少,所有R操作也更少,我们判断合法的时候也先判断右边相同也是为了使R尽可能集中在中间使两边的L更多,从而使字典序更小。
点击查看代码
#include <bits/stdc++.h> using namespace std; const int N=1e6+10; int n; int a[N]; int l[N],r[N],k; char ans[N]; int vis[N],cnt; signed main(){ ios::sync_with_stdio(false); cin.tie(nullptr); int t; cin>>t; while(t--){ cin>>n; memset(vis,0,sizeof vis); memset(a,0,sizeof a); k=0; cnt=0; for(int i=1;i<=2*n;i++){ cin>>a[i]; if(vis[a[i]]==0){ cnt++; } vis[a[i]]++; if(i>n){ vis[a[i-n]]--; if(vis[a[i-n]]==0){ cnt--; } } if(cnt==n){ l[++k]=i-n+1; r[k]=i; } } int flag=0; for(int q=k;q>=1;q--){ memset(ans,0,sizeof ans); int now=0; int ll=l[q],rr=r[q],sl=l[q]-1,sr=r[q]+1; while(ll<=rr){ if(a[sr]==a[ll]){ ans[n-now]='R'; ans[n+now+1]='L'; sr++; ll++; now++; } else if(a[sr]==a[rr]){ ans[n-now]='R'; ans[n+now+1]='R'; sr++; rr--; now++; } else if(a[sl]==a[ll]){ ans[n-now]='L'; ans[n+now+1]='L'; ll++; sl--; now++; } else if(a[sl]==a[rr]){ ans[n-now]='L'; ans[n+now+1]='R'; rr--; sl--; now++; } else{ break; } } if(now==n){ flag=1; break; } } if(flag==0){ cout<<-1<<"\n"; } else{ for(int i=1;i<=2*n;i++){ cout<<ans[i]; } cout<<"\n"; } } return 0; }
csp-s 2022
P8817 [CSP-S 2022] 假期计划
唉,还是自己想不出的题,马上要考试了,怎么办,非常慌,但我还是有必要记一下题解吧。
大神已经讲的非常清楚,口胡下做法得了,数据范围支持到 \(n^2\) 所以可能会排除些假做法,因为路径有四个点,所以贪心地看,选择了前三个a,b,c后就只能选一个最大的d了,同样的选择了b,c,d后就只能选最大的a了,所以我们枚举b,c同时找最大的a,d,但是可能会重点,所以要选出第二大和第三大的来保证没有相同的点,然后进行搭配选择即可。
P8818 [CSP-S 2022] 策略游戏
感觉非常复杂?对于现在的我还是有深度的,首先第一个大坑就是并不需要真的求出c矩阵,这个题意就是让你在区间中选数,但要求乘积最大,所以要分讨。
你假定 \(a_i\ge0\),那这时如果 \(min(b_i)\ge0\) 取 \(max(a_i)\),否则取 \(min(a_i\ge0)\),相反的,假定\(a_i<0\),那这时如果 \(max(b_i)\ge0\) 取 \(max(a_i)\),否则取 \(max(a_i<0)\)。
这就是贪心的思想,感觉非常有深度(菜),然后就需要维护6个ST表,非常糟糕啊,然后就没有然后了,你就慢慢维护去吧。
点击查看代码
#include<bits/stdc++.h> using namespace std; #define ll long long const int N=1e5+10; int a[N],b[N],lg[N]; int n,m,q; int mxa[N][20]; int mia[N][20]; int rmxa[N][20]; int rmia[N][20]; int mxb[N][20]; int mib[N][20]; int main(){ ios::sync_with_stdio(false); cin>>n>>m>>q; lg[1]=0; for(int i=2;i<=max(n,m);i++){ lg[i]=lg[i>>1]+1; } for(int i=1;i<=n;i++){ cin>>a[i]; mxa[i][0]=mia[i][0]=a[i]; rmia[i][0]=0<=a[i]?a[i]:INT_MAX;//正数中取最小,没正数取intmin标记为无 rmxa[i][0]=a[i]<0?a[i]:INT_MIN;//负数中取最大,没负数取intmax标记为无 } for(int i=1;i<=m;i++){ cin>>b[i]; mxb[i][0]=mib[i][0]=b[i]; } for(int j=1;j<=lg[n];j++){ for(int i=1;i<=n-(1<<j)+1;i++){ int p=i+(1<<(j-1)); mxa[i][j]=max(mxa[i][j-1],mxa[p][j-1]); rmxa[i][j]=max(rmxa[i][j-1],rmxa[p][j-1]); mia[i][j]=min(mia[i][j-1],mia[p][j-1]); rmia[i][j]=min(rmia[i][j-1],rmia[p][j-1]); } } for(int j=1;j<=lg[m];j++){ for(int i=1;i<=n-(1<<j)+1;i++){ int p=i+(1<<(j-1)); mxb[i][j]=max(mxb[i][j-1],mxb[p][j-1]); mib[i][j]=min(mib[i][j-1],mib[p][j-1]); } } while(q--){ int la,ra,lb,rb; cin>>la>>ra>>lb>>rb; int x=lg[ra-la+1],y=lg[rb-lb+1]; int pa=ra-(1<<x)+1,pb=rb-(1<<y)+1; int mmxa=max(mxa[la][x],mxa[pa][x]); int rmmxa=max(rmxa[la][x],rmxa[pa][x]); int mmia=min(mia[la][x],mia[pa][x]); int rmmia=min(rmia[la][x],rmia[pa][x]); int mmxb=max(mxb[lb][y],mxb[pb][y]); int mmib=min(mib[lb][y],mib[pb][y]); long long ans=LONG_LONG_MIN; ans=max(ans,(ll)mmxa*(mmxa>=0?mmib:mmxb)); ans=max(ans,(ll)mmia*(mmia>=0?mmib:mmxb)); if(rmmxa!=INT_MIN){ ans=max(ans,(ll)rmmxa*(rmmxa>=0?mmib:mmxb)); } if(rmmia!=INT_MAX){ ans=max(ans,(ll)rmmia*(rmmia>=0?mmib:mmxb)); } cout<<ans<<"\n"; } return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具