高一下二调
OI赛制 三个半小时 四道题
T1:
eee——唐氏大水题,也是成功唐了一波,这题直接用暴力 swap交换数字及下标
A了~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Code:
查看代码
#include <bits/stdc++.h> using namespace std; const int N=1e6+10; int n,a,cnt,id[N],xb[N];//id即输入的数,xb存每个数的下标 bool flag; int main(){ freopen("seat.in","r",stdin); freopen("seat.out","w",stdout); cin>>n; for(int i=1;i<=n;i++){ cin>>id[i]; xb[id[i]]=i; } for(int i=1;i<=n;i++){ while(id[i]!=i){ int a=id[i]; swap(id[i],id[xb[i]]); swap(xb[i],xb[a]); cnt++; } } cout<<cnt; return 0; } /* 8 5 4 2 3 6 8 7 1 */
T2:
点击查看图片
%%%%%梦中的梦中~~~%%%%%,呃呃这道题也是俺从文革上一道区间dp的改编题啊,不过这区间dp是真的想不出来,抽象
详解可见 俺从文革《金字塔》一题题解,也是小小的水了一波
直接上Code:
查看代码
#include <bits/stdc++.h> #define int long long using namespace std; const int N=310,mod=1e9; string s; int f[N][N]; int solve(int l,int r){ if(l>r) return 0; if(l==r) return 1; if(f[l][r]!=-1) return f[l][r]; f[l][r]=0; for(int k=l+2;k<=r;k++) if(s[k]==s[l]) f[l][r]=(f[l][r]+(long long)solve(l+1,k-1)*solve(k,r))%mod; return f[l][r]; } main(){ freopen("school.in","r",stdin); freopen("school.out","w",stdout); cin>>s; memset(f,-1,sizeof(f)); cout<<solve(0,s.size()-1)<<endl; }
T3:
差分约束 糖果原题,甚至数据一模一样
Code:
查看代码
#include<bits/stdc++.h> #define int long long using namespace std; const int N=100010; struct stu{ int X,A,B; }q[N]; int n,k,a[N]; main(){ freopen("bomb.in","r",stdin); freopen("bomb.out","w",stdout); cin>>n>>k; for (int i=1;i<=k;i++) cin>>q[i].X>>q[i].A>>q[i].B; for (int i=1;i<=n;i++) a[i]=1; for (int t=1;t<=200;t++){ for (int i=1;i<=k;i++){ if (q[i].X==1){ if (a[q[i].A]>a[q[i].B]) a[q[i].B]=a[q[i].A]; else a[q[i].A]=a[q[i].B]; } else if (q[i].X==2){ if (a[q[i].A]>=a[q[i].B]) a[q[i].B]=a[q[i].A]+1; } else if (q[i].X==3){ if (a[q[i].A]<a[q[i].B]) a[q[i].A]=a[q[i].B]; } else if (q[i].X==4){ if (a[q[i].A]<=a[q[i].B]) a[q[i].A]=a[q[i].B]+1; } else if (q[i].X==5){ if (a[q[i].A]>a[q[i].B]) a[q[i].B]=a[q[i].A]; } } } for (int i=1;i<=k;i++){ if (q[i].X==1){ if (a[q[i].A]>a[q[i].B]) {cout<<"-1";return 0;} } else if (q[i].X==2){ if (a[q[i].A]>=a[q[i].B]) {cout<<"-1";return 0;} } else if (q[i].X==3){ if (a[q[i].A]<a[q[i].B]) {cout<<"-1";return 0;} } else if (q[i].X==4){ if (a[q[i].A]<=a[q[i].B]) {cout<<"-1";return 0;} } else if (q[i].X==5){ if (a[q[i].A]>a[q[i].B]) {cout<<"-1";return 0;} } } long long ans=0; for(int i=1;i<=n;i++) ans+=a[i]; cout<<ans<<endl; return 0; }
T4:
二分?No,No,No,直接就被卡掉,优先队列即可,将成绩从大到小,或者从小到大排序,然后枚举中位数,在中位数左边和右边查询最小的n/2个元素和。
用动态规划一样的思路处理出从左到右边区间里面有n/2个元素和的最小值,再处理出从右到左的最小值。产生区间里面这个最小值的元素我们用一个大根堆去维护,
每次和堆顶元素比较,如果小就换掉。预处理完,然后就来一遍for循环,比较一下就好了。
看了一眼题解中的可持续化线段树和主席树.......根本不会 太蒟蒻了%%%%%
Code:
查看代码
#include <bits/stdc++.h> #define N 200010 using namespace std; int n,c,maxx,sum,f[N],g[N]; priority_queue<int> q; struct node{ int score,w;//score为猪的CSAT成绩,w为奖学金 }a[N]; bool cmp(node a,node b){ return a.score<b.score; } int main(){ freopen("money.in","r",stdin); freopen("money.out","w",stdout); cin>>n>>c>>maxx; for(int i=1;i<=c;i++) cin>>a[i].score>>a[i].w; sort(a+1,a+1+c,cmp); for(int i=1;i<=n/2;i++){ sum+=a[i].w; q.push(a[i].w); } for(int i=n/2+1;i<=c;++i){ f[i]=sum; int top=q.top(); if(top>a[i].w){ q.pop(); sum-=top; sum+=a[i].w; q.push(a[i].w); } } sum=0; while(!q.empty()) q.pop(); for(int i=c;i>=c-n/2+1;i--){ sum+=a[i].w; q.push(a[i].w); } for(int i=c-n/2;i>=1;i--){ g[i]=sum; int top=q.top(); if(top>a[i].w){ q.pop(); sum-=top; sum+=a[i].w; q.push(a[i].w); } } for(int i=c-n/2;i>=n/2+1;i--) if(a[i].w+f[i]+g[i]<=maxx){ cout<<a[i].score; return 0; } cout<<-1; return 0; } /* 3 7 15 1 1 2 2 3 12 4 4 5 5 6 6 7 7 */
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】