【Codeforces Round #509 (Div. 2)】A,B,C,D
阿新 • • 發佈:2018-12-10
這是蒟蒻的真·第一場CF...所以其實升了1500+還是不錯吧?
題意:找包含給出的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; }
題意:給出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; }
題意:
- 工作日持續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]]<<" "; }
題意:
- 一架飛機在地面以上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;
}
——時間劃過風的軌跡,那個少年,還在等你。