Educational Codeforces Round 79 题解
A题
此类直线排列问题都可以先对输入排序,把最大的用光再看,一般都考虑插入。
如果C>A+B+1,那么必定不行。
考虑C<=A+B+1,我们可以贪心的想,肯定是要将AB插完后尽量使AB的差距小,这样才可以对剩下的AB进行排
我们可以发现,在人为操作下,可以最终使得B=A+1或B=A,可以先插B,插到跟A一样的时候,再交替插,这样就能达到目的。
显然这两种情况都可以,所以C<=A+B+1是可行的。
B题
因为本题只能跳过一次,然后必须是按顺序才背,就可以使用贪心的想法,找到满足要求的最大值,那么答案就是他,满足要求的意思就是指,剩下的时间大于等于前i项减去他的值,因为这样是可以背诵的。
#include<iostream> #include<cstdio> #include<cstring> #include<string> #include<algorithm> using namespace std; typedef long long ll; const int N=100010; int a[N]; int main(){ int t; cin>>t; while(t--){ int n,s; cin>>n>>s; int i; for(i=1;i<=n;i++) cin>>a[i]; ll sum=0; for(i=1;i<=n;i++){ sum+=a[i]; } if(sum<=s){ cout<<0<<endl; continue; } ll mx=0; ll ansid=0; ll now=0; ll mxid=0; for(i=1;i<=n;i++){ now+=a[i]; if(mx<a[i]){ mx=a[i]; mxid=i; } if(now-mx<=s){ ansid=mxid; } } cout<<ansid<<endl; } }
C题
本题也是个思维题,我们明白我们可以对在所求上方的值人为排序,那么我们只需要求目前能到的最深度即可,在最深以上的都可以用1s,深度以下的需要求上方还有多少个,这也容易求,因为进行了几次就少几个
并且少的都在当前的位置之上。
所以我们要求一个位置数组,之后遍历就可,注意爆int
#include<iostream> #include<cstdio> #include<cstring> #include<string> #include<algorithm> using namespace std; typedef long long ll; const int N=100010; int a[N]; int b[N]; int pos[N]; int main(){ int n,t; cin>>t; while(t--){ memset(a,0,sizeof a); memset(b,0,sizeof b); int m; cin>>n>>m; int i; for(i=1;i<=n;i++){ scanf("%d",&a[i]); pos[a[i]]=i; } for(i=1;i<=m;i++) scanf("%d",&b[i]); int npos=-1; ll res=0; for(i=1;i<=m;i++){ if(pos[b[i]]<npos){ res++; } else{ npos=pos[b[i]]; res+=(pos[b[i]]-1-(i-1))*2; res++; } } cout<<res<<endl; } }
没有人不辛苦,只有人不喊疼