地址:http://codeforces.com/contest/1334
题意:给出n组同一时间的游戏完成数和消除数。按顺序排列。问是否符合实际。
解析:这个题意挺长,刚开始是有点懵的。根据题意,随着时间流逝,游戏数不会减少,消除数也不会减少(根据样例也能看出)。一个玩家成功完成一次,那么游戏数和消除数同一时间+1。来一个新人,游戏数也会增加。那么游戏数的增加要>=消除数的增加。记得n==1时,特判p[1]>=c[1]。
#include<iostream> #include<cstdio> #include<cmath> #include<cstring> using namespace std; typedef long long ll; const int maxn=1e2+10; int p[maxn],c[maxn]; int main() { int t; cin>>t; while(t--) { int n; cin>>n; for(int i=1;i<=n;i++) cin>>p[i]>>c[i]; int ok=0; if(p[1]<c[1]) { cout<<"NO"<<endl;continue; } for(int i=2;i<=n;i++) { if(p[i]<p[i-1]||c[i]<c[i-1]) ok=1; if(p[i]-p[i-1]<c[i]-c[i-1]) ok=1; } if(ok) cout<<"NO"<<endl; else cout<<"YES"<<endl; } }
题意:每个人有一些财富,财富>=x的为富人。任意选一些人的财富进行平均。问可实现的最大富人数。
解析:从大到小排序,依次进行平均分配,当平均值<x时break掉。
#include<iostream> #include<cstdio> #include<cmath> #include<algorithm> #include<cstring> using namespace std; typedef long long ll; const int maxn=1e5+20; ll a[maxn]; bool cmp(ll a,ll b) { return a>b; } int main() { int t; cin>>t; while(t--) { ll n,m; cin>>n>>m; for(int i=0;i<n;i++) cin>>a[i]; sort(a,a+n,cmp); ll k=0; ll sum=0; for(k=0;k<n;k++) { sum+=a[k]; ll mid=(ll)sum/(k+1); if(mid<m) { break; } } cout<<k<<endl; } }
题意:n个怪物,ai为生命值,bi为杀死本怪物爆炸对接下来的怪物造成的伤害值,下一个死不了就要补枪。怪物顺时针排列。开一枪生命值-1,问消灭所有怪物需要的最少开枪数。
解析:由于顺序已规定好,而且每个怪物死了以后只对下一个怪物有影响。所以我们只需要决定先消灭谁,接下来就按顺序计算即可。先选择 i 位置,那么i-1位置到i位置的花费就不需要管了,因为i位置的怪物已经死掉了。用v[i]=a[i]-b[i-1]来预处理差分和,对v[]进行累加得到sum,接下来枚举每一个点。那么以这些点作为起始点,消灭所有的怪物的花费就是sum-v[i]+a[i]。下面拿样例来模拟一下:
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<set> using namespace std; typedef long long ll; const int maxn=3e5+100; ll v[maxn]; ll a[maxn],b[maxn]; int main() { int t; scanf("%d",&t); while(t--) { int n; scanf("%d",&n); for(int i= 0;i < n;i++) scanf("%lld%lld",&a[i],&b[i]); ll sum=0; for(int i=0;i<n;i++) { if(i==0) { v[i]=a[0]-b[n-1]; if(v[i]<0) v[i]=0; } else { v[i]=a[i]-b[i-1]; if(v[i]<0) v[i]=0; } sum+=v[i]; } ll minn=sum-v[0]+a[0]; //最好直接把第一个minn算出来,否则需要弄一个很大的数 for(int i=1;i<n;i++) { minn=min(minn,sum-v[i]+a[i]); } cout<<minn<<endl; } }