hdu 4968 Improving the GPA 策略 2014 Multi-University Training Contest 9-1009

题意:

给定一个平均分数s,和一个课程数n,根据GPA表,求最大的可能GPA和最小的GPA。

题解:

根据表,我们发现在70-85这段中学分是等比例的,即每增加5分,学分增加0.5.

为了便于计算,我们将学分换算*2.

我们发现只要是70-85段无论怎么增加减少总的学分是不变,只有85-100和60-69段学分不成比例,所以我们需要通过这两段使得GPA最大和最小。

GPA最大,我们就尽可能多的选择85,那么就会有更多的数趋近与60(即使平均分大于85也没事,因为那样的效果等价于全选85),为什么这样学分会更加的多,拿75 5来说,

编程了85 85 60 60 60,根据正常积分比(就是70-85段的积分比),60要比65的学分少0.5,而实际呢,没有减少,也就说多余出了3个5分(即3个60多出来的),那么就可以再原则上多出了1.5学分了。

GPA最小,跟上面同理,尽可能选多的69分(这样都是最小的2.0),那么剩余的趋近100分,相对于85分,浪费了15分。


代码:

#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <vector>
#include <cctype>
using namespace std;

int func(int x)
{
    if(x>=85)return 8;
    else if(x>=80)return 7;
    else if(x>=75)return 6;
    else if(x>=70)return 5;
    else return 4;
}
int main()
{
    int n,s,T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d",&s,&n);
        int i,j,k,p,q,maxv=0,minv=0;
        p=s*n;
        for(i=1;i<=n;i++)
        {
            if((p-85)<60*(n-i))
            {
                maxv+=func(p-60*(n-i));
                maxv+=4*(n-i);
                break;
            }
            p-=85;
            maxv+=8;
        }
        p=s*n;
        for(i=1;i<=n;i++)
        {
            if((p-69)>100*(n-i))
            {
                minv+=func(p-100*(n-i));
                minv+=8*(n-i);
                break;
            }
            p-=69;
            minv+=4;
        }
        printf("%.4f %.4f\n",0.5*minv/n,0.5*maxv/n);
    }
    return 0;
}


你可能感兴趣的:(策略)