A. Initial Bet
不解释。。
#include <iostream>
#include <stdio.h>
#include <cmath>
#include <algorithm>
#include <iomanip>
#include <cstdlib>
#include <string>
#include <memory.h>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <ctype.h>
#include <sstream>
#define INF 1000000000
#define ll long long
#define min3(a,b,c) min(a,min(b,c))
#define max3(a,b,c) max(a,max(b,c))
#define MAXN 1010
using namespace std;
int a[7];
int main(){
int s=0;
for(int i=1;i<=5;i++){
cin>>a[i];
s+=a[i];
}
if(s%5==0&&s/5!=0){
cout<<s/5<<endl;
}else{
cout<<-1<<endl;
}
return 0;
}
B. Random Teams
思路:贪心。照着样例贪心就可以了,最小的情况是平均分组,最大的情况是其中一组人尽可能多,其他组只有1人。计算的时候套一下公式。
#include <iostream>
#include <stdio.h>
#include <cmath>
#include <algorithm>
#include <iomanip>
#include <cstdlib>
#include <string>
#include <memory.h>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <ctype.h>
#include <sstream>
#define INF 1000000000
#define ll long long
#define min3(a,b,c) min(a,min(b,c))
#define max3(a,b,c) max(a,max(b,c))
#define MAXN 1010
using namespace std;
int main(){
ll n,m;
while(cin>>n>>m){
ll tmp=(n/m+1);
ll tmp2=(n/m);
cout<<(tmp-1)*(tmp)*(n%m)/2+(tmp2-1)*tmp2*(m-n%m)/2<<" ";
n-=m;
cout<<(n+1)*n/2<<endl;
}
return 0;
}
C. Table Decorations
思路:贪心。每次拿一个rgb中最少的那种气球,和两个rgb中最多的那种气球拼,最后检查能否三种各拿一个。但是纯暴力这样搞会超时,所以每次折半拿。比赛的时候犯2了,结果跪了。不过在离比赛结束不到4min的时候hack成功一发,哈哈,这题其实黑点不少。。另外见过有人代码一个公式就出来的,表示不懂。。
#include <iostream>
#include <stdio.h>
#include <cmath>
#include <algorithm>
#include <iomanip>
#include <cstdlib>
#include <string>
#include <memory.h>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <ctype.h>
#include <sstream>
#define INF 1000000000
#define ll long long
#define min3(a,b,c) min(a,min(b,c))
#define max3(a,b,c) max(a,max(b,c))
#define MAXN 1010
using namespace std;
ll c[3];
int main(){
while(cin>>c[0]>>c[1]>>c[2]){
sort(c,c+3);
ll ans=0;
while(c[0]){
if(c[2]<2)break;
ll t=c[0]/2;
if(t==0&&c[0]==1)t++;
ans+=t;
c[0]-=t;
c[2]-=t*2;
sort(c,c+3);
}
while(c[1]){
if(c[2]<2)break;
ll t=c[1]/4;
if(t==0&&c[1]>=1)t++;
ans+=t;
c[1]-=t;
c[2]-=t*2;
sort(c,c+3);
}
if(c[0]&&c[1]&&c[2])ans++;
cout<<ans<<endl;
}
return 0;
}
D. Red-Green Towers
思路:DP(背包)。需要滚动数组,否则爆内存。其实这题的模型可以转化为把一个数分解为若干个不同的数相加的和,问有多少种相加方法,其实也就是背包。。首先我们应该计算出最高高度h(直接用r+g来算,只有它们的和会影响可达高度),还有可使用红积木的区间(也就是搭最高高度会剩余积木的话,可以多用一些红的也可以多用一些绿的),然后对r去跑一遍背包,跑的过程中对区间内的相加计算结果。
#include <iostream>
#include <stdio.h>
#include <cmath>
#include <algorithm>
#include <iomanip>
#include <cstdlib>
#include <string>
#include <memory.h>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <ctype.h>
#include <sstream>
#define INF 1000000000
#define ll long long
#define min3(a,b,c) min(a,min(b,c))
#define max3(a,b,c) max(a,max(b,c))
#define MAXN 1010
using namespace std;
int dp[200010];
int main(){
int r,g;
while(cin>>r>>g){
int s=r+g;
int t=0;
ll h;
for(int i=1;;i++){
t+=i;
if(t>s){
t-=i;
h=i-1;
break;
}
}
int minr=h*(h+1)/2-g;
//max h is 893
dp[0]=1;
ll ans=0;
for(ll i=1;i<=h;i++){
for(int j=r;j>=0;j--){
if(j-i>=0&&dp[j-i]){
dp[j]+=dp[j-i];
dp[j]%=1000000007;
}
if(i==h&&j>=minr){
ans+=dp[j];
ans%=1000000007;
}
}
}
cout<<ans<<endl;
}
return 0;
}