版权声明:https://blog.csdn.net/flora715 https://blog.csdn.net/flora715/article/details/82731940
这是蒟蒻的真·第一场CF...所以其实升了1500+还是不错吧?
A. Heist
题意:找包含给出的n个数的最短连续序列,输出新加入的数的最小个数。
分析:排序+扫描即可。
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
typedef unsigned long long ll;
ll a[5019];
int main(){
ll n,ans=0; cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
sort(a+1,a+n+1);
for(int i=2;i<=n;i++)
ans+=a[i]-a[i-1]-1;
cout<<ans<<endl;
}
B. Buying a TV Set
题意:给出a,b,x,y,计算正整数w和h的对数,使得w≤a,h≤b,w/h=x/y。
分析:对于x、y,求二者的gcd(最大公约数),得出约分后的w/h,
确定a、b能包含的w、h倍数上界即可。
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
typedef unsigned long long ll;
//计算正整数w和h的对数,w≤a,h≤b,w/h=x/y
ll gcd(ll a,ll b){
ll r;
while(b>0){ r=a%b; a=b; b=r; }
return a;
}
int main(){
ll a,b,x,y,ans=0; cin>>a>>b>>x>>y;
ll gcds=gcd(x,y); ll dx=x/gcds,dy=y/gcds;
ll cnt=min((ll)a/dx,(ll)b/dy);
cout<<cnt<<endl;
}
C. Coffee Break
题意:
- 工作日持续m分钟。期间有n分钟可以选择喝咖啡:a1,a2,......每次一分钟。
- 每天的任意两次喝咖啡至少间隔d分钟。希望在最短时间内完成n次咖啡时间。
- 对于每个给定的分钟,确定一天,在此期间Monocarp应该在这一分钟喝咖啡。
- 你必须尽量减少花费的天数。 并输出每个时间对应的天数。
分析:用set维护min元素,增加天数判断可行性即可,注意每次喝咖啡需要一分钟。
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<map>
#include<set>
using namespace std;
typedef unsigned long long ll;
/*【C】
工作日持续了m分钟。工作期间有n分钟可以选择喝咖啡:a1,a2,......每次一分钟。
每天的任意两次喝咖啡至少间隔d分钟。 希望在最短的工作日内完成这些n次咖啡休息时间。
对于每个给定的分钟,确定一天,在此期间Monocarp应该在这一分钟喝咖啡休息。
你必须尽量减少花费的天数。 并输出每个时间对应的天数。 */
ll a[200009];
map<int,int> maps;
set<int> ss;
int main(){
ll n,m,d; cin>>n>>m>>d;
for(ll i=1;i<=n;i++){
cin>>a[i]; maps[a[i]]=0; ss.insert(a[i]);
}
int ans=1,cnt=0;
while(!ss.empty()){
set<int>::iterator it=ss.lower_bound(cnt);
if(it==ss.end()) cnt=0,ans++;
else{ cnt=*it+1+d, maps[*it]=ans, ss.erase(it); }
}
cout<<ans<<endl;
for(ll i=1;i<=n;i++) cout<<maps[a[i]]<<" ";
}
D. Glider
题意:
- 一架飞机在地面以上h米的恒定高度飞行。
- 从飞机上跳下后,飞行员将飞向与飞机相同的方向,与x轴平行。
- 每秒覆盖一个距离单位。当然,他也会下降,y坐标每秒减少一个单位。
- 在某些段上有上升的气流,每个这样的段由两个数字x1、x2表示。
- 没有两个部分共享任何共同点。当滑翔机在其中一个区段内时,他不会下降。
- 如图:在1处跳出,他将在10点停止。在2点跳出,他将在12点停止。
- 如果滑翔机可以选择任何整数坐标从飞机上跳起并开始飞行,
- 则确定沿着Ox轴从滑翔机飞行开始的点到飞行结束点的最大距离。
- 接触地面后将完全停止,因此如果第二个坐标为0,则无法滑过上升的气流段。
分析:维护两个sum数组。sum1[ ]表示气流段包含距离的前缀和,
sum2[ ]表示非气流段包含距离的前缀和(可以不用,只是为了处理方便)。
用双指针的方法维护head、tail,按照转移方程:
ans=max(ans,h+sum1[tail]-max(0,sum1[head-1]));
进行转移。注意双指针的起点和变化模式。
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<map>
#include<set>
using namespace std;
typedef unsigned long long ll;
/*【D】*/
ll sum1[200019],sum2[200019];
int main(){
ll n,h,le,ri,lastt=0; cin>>n>>h;
for(ll i=1;i<=n;i++){
cin>>le>>ri; sum1[i]=sum1[i-1]+ri-le;
sum2[i]=sum2[i-1]+le-lastt; lastt=ri;
} ll head=0,tail=1,ans=h;
while(head<=n&&tail<=n){
while(sum2[tail]-sum2[head]<h&&tail<=n){
ans=max(ans,h+sum1[tail]-max((ll)0,sum1[head-1])); tail++;
} head++;
} cout<<ans<<endl;
}
——时间划过风的轨迹,那个少年,还在等你。