题解:P13312 [GCJ 2012 Qualification] Dancing With the Googlers
abc1234shi · · 题解
看到题解区的题解都很复杂、绕口,于是想写一篇大家都能看懂的题解。
分析
贪心加数学理论。
思路
普通情况很好算,将三次总和直接除
接下来看令人惊讶的情况。这里加特判,如果三次总和小于
我们设最小分数为
那我们就来分类讨论:
-
若
k=x ,则三数总和为x+x+x+2=3x+2 ,这里求出最大分数x+2 可以选择将总和先加4 再除3 ,或者将总和加2 或3 向上取整都能求出最大分数x+2 。 -
若
k=x+1 ,则三数总和为x+x+x+2+1=3x+3 ,这里求出最大分数x+2 可以选择将总和先加3 再除3 ,或者将总和加1 或2 向上取整都能求出最大分数x+2 。 -
若
k=x+2 ,则三数总和为x+x+x+2+2=3x+4 ,这里求出最大分数x+2 可以选择将总和先加2 再除3 ,或者将总和加1 向上取整都能求出最大分数x+2 。
我们需要找到一个式子,使得在三种中间数的取值中都能正确的算出
接下来进行判断,我们定义两个变量:一个存储答案数量;一个存储三元组满足原本最大分数不大于等于
那么如果原本最大分数就大于等于
接下来再进行判断,如果预答案数量大于等于规定的令人惊讶的三元组数量,就将答案变量增加题目规定的令人惊讶的三元组数量。否则就将答案变量增加预答案数量。
代码
#include<bits/stdc++.h>
using namespace std;
int a[110000];
int main(){
int t;
cin>>t;
for(int rt=1;rt<=t;rt++){
int n,s,p;
cin>>n>>s>>p;
int ans=0,sum=0;
for(int i=1;i<=n;i++)cin>>a[i];
for(int i=1;i<=n;i++){
int h;
if(a[i]==0||a[i]==1||a[i]==29||a[i]==30){
if(ceil(1.00*a[i]/3)>=p)sum++;
}
else if(ceil(1.00*a[i]/3)>=p){
sum++;
}
else {
h=ceil((2+1.00*a[i])/3);
if(h>=p)ans++;
}
}
if(ans>=s)sum+=s;
else sum+=ans;
cout<<"Case #"<<rt<<": "<<sum<<endl;
}
return 0;
}