高一下二调

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
*/

 

 

点击查看Goat

点击分享热爱

一名爱打篮球的oier#

posted @   __kw  阅读(44)  评论(1编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示