Codeforces Round #437 (Div. 2, based on MemSQL Start[c]UP 3.0 - Round 2)
Problem A
水题,水一水。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<bits/stdc++.h> 2 using namespace std; 3 int n; 4 char s[200]; 5 int main() 6 { 7 cin>>n; 8 int cnt1=0,cnt2=0; 9 scanf("%s",s); 10 for(int i=0;i<n-1;i++) 11 { 12 if(s[i]=='S' && s[i+1]=='F') cnt1++; 13 else if(s[i]=='F' && s[i+1]=='S') cnt2++; 14 } 15 if(cnt1>cnt2) puts("YES"); 16 else puts("NO"); 17 return 0; 18 }
Problem B
题目大意:给你数字n,让你给出一个钱的总数m,和钱的种类n个,要求用这些种类的钱
构成m的种数为n。
思路:我是用5和2两种钱构造的,我们考虑构成10 的种数一共只有两种,一种是2 2 2 2 2,另一种是
5 5,那么20 就是三种,30就是四种,40就是五种,一直这样构造下去,忘了考虑一种情况WA了一次。。。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<bits/stdc++.h> 2 using namespace std; 3 int n; 4 int main() 5 { 6 scanf("%d",&n); 7 if(n==1) 8 { 9 puts("1 1"); 10 puts("1"); 11 return 0; 12 } 13 printf("%d 2\n",(n-1)*10); 14 puts("5 2"); 15 return 0; 16 }
Promblem C
题目大意:现在有n个人需要吃si 片披萨,一共有两种披萨A,B,第i个人吃一片A披萨获得的
愉悦值为ai,B为bi,一块披萨能分成S片,我们要买最少的披萨,问你最大愉悦值是多少。
思路:我们先让每个人吃获得愉悦值大的披萨,然后统计A披萨的片数和B披萨的片数,
A和B对S 取膜,剩下的就是不确定的,如果A+B>S则买两种披萨各一个,如果A+B<=S
则买一个披萨,两种披萨都模拟一遍取愉悦值大的。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> #define ll long long using namespace std; const int N=1e5+5; ll _abs(ll x) { if(x>=0) return x; else return -x; } struct node { ll s,a,b; bool operator < (const node &rhy)const { return _abs(a-b)<_abs(rhy.a-rhy.b); } }p[N]; ll n,S; ll work(ll c1,ll c2) { ll ans=0; if(c1) { for(int i=0;i<n;i++) { if(p[i].a<p[i].b) continue; if(p[i].s>=c1) ans+=c1*(p[i].a-p[i].b); else ans+=p[i].s*(p[i].a-p[i].b); c1-=p[i].s; if(c1<=0) break; } } else { for(int i=0;i<n;i++) { if(p[i].a>=p[i].b) continue; if(p[i].s>=c2) ans+=c2*(p[i].b-p[i].a); else ans+=p[i].s*(p[i].b-p[i].a); c2-=p[i].s; if(c2<=0) break; } } return ans; } int main() { cin>>n>>S; ll sum=0,ans=0; ll res1=0,res2=0; for(int i=0;i<n;i++) { scanf("%I64d%I64d%I64d",&p[i].s,&p[i].a,&p[i].b); ans+=p[i].s*max(p[i].a,p[i].b); if(p[i].a>=p[i].b) res1+=p[i].s; else res2+=p[i].s; } res1=res1%S; res2=res2%S; if(res1+res2>S) { printf("%I64d\n",ans); return 0; } ll res=1e18; sort(p,p+n); res=min(res,work(0,res2)); res=min(res,work(res1,0)); printf("%I64d\n",ans-res); return 0; }
Problem E
题目大意:给你一些股票每天的价格,每一天你可以选择买,卖,或者啥都不干,问你
利润最大多少。
思路:智力题,我不会! 用优先队列维护最小值,我们取一个数b,如果这个数比堆顶的
元素a小,则将b加入优先队列,如果b比a大,删除a,加入两个b,(b-a)加入ans,
第一个b相当于把a变成了b,第二个b是自身。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int N=3*1e5+5; 4 int n,a[N]; 5 int main() 6 { 7 scanf("%d",&n); 8 for(int i=1;i<=n;i++) scanf("%d",&a[i]); 9 priority_queue<int,vector<int>,greater<int> > Q; 10 long long ans=0; 11 for(int i=1;i<=n;i++) 12 { 13 if(Q.empty()) 14 { 15 Q.push(a[i]); 16 continue; 17 } 18 int t=Q.top(); 19 if(t>=a[i]) Q.push(a[i]); 20 else 21 { 22 ans+=a[i]-t; 23 Q.pop(); 24 Q.push(a[i]); Q.push(a[i]); 25 } 26 } 27 printf("%I64d\n",ans); 28 return 0; 29 }