鏈接:https://codeforces.com/contest/1313
來源:codeforces
文章目錄
A. Fast Food Restaurant(貪心)
思路:直接貪心的取,對三個數進行排序,貪心匹配
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
int a[maxn];
int main(){
int T; scanf("%d",&T);
while(T--){
scanf("%d%d%d",&a[1],&a[2],&a[3]);
sort(a+1,a+4);
if(a[3]==0) puts("0");
else if(a[2]==0) puts("1");
else if(a[1]==0){
int cnt=2;
a[2]--; a[3]--;
if(a[2]) cnt++;
printf("%d\n",cnt);
}else{
int cnt=3;
a[1]--; a[2]--; a[3]--;
if(a[1]&&a[3]) { a[3]--;a[1]--;cnt++; }
if(a[2]&&a[3]) { a[3]--;a[2]--;cnt++; }
if(a[1]&&a[2]) { a[1]--;a[2]--;cnt++; }
if(a[1]&&a[2]&&a[3]) cnt++;
printf("%d\n",cnt);
}
}
return 0;
}
B. Different Rules(思維)
思路: 這個區間的數字無論和誰組合都會小於等於 ,所以這些數字無論如何組合都不會大於 我們考慮 和什麼數字相加的時候等於 ,那麼這個區間以內的數都可以互相結合小於等於 此區間就是 。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main(){
int T; scanf("%d",&T);
while(T--){
ll n,l,r;
scanf("%lld%lld%lld",&n,&l,&r);
printf("%lld %lld\n",min(max((l+r)-n+1,1ll),n),min(l+r-1,n));
}
return 0;
}
C1. Skyscrapers (easy version)(枚舉)
思路:我們枚舉每一個峯值,那麼他左邊的數字一定都是遞減的,右邊的數字一定都是遞增的,直接枚舉判斷即可。注意數據範圍:long long
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e3+10;
int a[maxn],b[maxn];
int main(){
int n; scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
ll MMax=INT_MIN; int inx=-1;
for(int i=1;i<=n;i++){
int Max=a[i]; ll sum=a[i];
for(int j=i-1;j>=1;j--) { Max=min(a[j],Max); b[i]=Max; sum+=(ll)b[i]; }
Max=a[i];
for(int j=i+1;j<=n;j++) { Max=min(a[j],Max); b[i]=Max; sum+=(ll)b[i]; }
// for(int j=1;j<=n;j++) cout<<b[i]<<" ";
if(MMax<sum) { MMax=sum;inx=i; }
}
int Max=a[inx];
for(int i=inx;i>=1;i--) { Max=min(a[i],Max); a[i]=Max; }
Max=a[inx];
for(int i=inx;i<=n;i++) { Max=min(a[i],Max); a[i]=Max; }
for(int i=1;i<=n;i++) printf("%d%c",a[i],i==n?'\n':' ');
return 0;
}
C2. Skyscrapers (hard version)(單調棧)
思路:此題目相對於上面一題只是數據範圍發生了變化,在找峯值的時候,對於左右兩邊的和我們可以進行優化,我們找到每個數字左側的小於等於它本身的第一個數,右側小於等於它本身的最後一個數。(這個過程可以通過單調棧來實現),接下來我們就可以計算出來每一點爲峯值的時候它左右兩側的和(兩邊都是遞減的)。然後遍歷數組找到和最大的那個點。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=5e5+10;
int a[maxn];
stack<int>stk;
int l[maxn],r[maxn];
ll L[maxn],R[maxn];
int main(){
int n; scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
for(int i=1;i<=n;i++){
while(stk.size()&&a[stk.top()]>a[i]) stk.pop();
if(stk.empty()) l[i]=0;
else l[i]=stk.top();
stk.push(i);
}
while(stk.size()) stk.pop();
for(int i=n;i>=1;i--){
while(stk.size()&&a[stk.top()]>a[i]) stk.pop();
if(stk.empty()) r[i]=n+1;
else r[i]=stk.top();
stk.push(i);
}
//for(int i=1;i<=n;i++) cout<<l[i]<<" "<<r[i]<<endl;
for(int i=1;i<=n;i++) L[i]=L[l[i]]+1ll*(i-l[i])*a[i];
for(int i=n;i>=1;i--) R[i]=R[r[i]]+1ll*(r[i]-i)*a[i];
//for(int i=1;i<=n;i++) cout<<L[i]<<" "<<R[i]<<endl;
ll MaxUp=INT_MIN; int inx=-1;
for(int i=1;i<=n;i++){
ll res=L[i]+R[i]-(ll)a[i];
if(MaxUp<res){
MaxUp=res;
inx=i;
}
}
int MaxPre=a[inx],MaxSuf=a[inx];
for(int i=inx;i>=1;i--) { MaxPre=min(a[i],MaxPre); a[i]=MaxPre; }
for(int i=inx;i<=n;i++) { MaxSuf=min(a[i],MaxSuf); a[i]=MaxSuf; }
for(int i=1;i<=n;i++) printf("%d%c",a[i],i==n?'\n':' ');
return 0;
}