UVa #1612 Guess (习题8-8)

本文介绍了一个UVa在线竞赛题目8-8.1612的解决方案,详细解释了如何通过计算每位参赛者的可能得分并排序,结合排名信息来找出最大得分的方法。文章提供了具体的实现代码,并分享了避免使用浮点数减少错误的技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

因为一共只有三道题,所以每个人的得分最多有8种可能性。把这8种可能性都算出来,存在数组里,排好序备用


排名就是一个天然的链表,给出了扫描的顺序


扫描时,维护两个变量:前一个player的最大得分 recd 和他的ID recdID


扫描到每个player时,从大到小遍历他的8种得分,如果有等于recd的得分,且这个player的ID大于recdID,则只需更新recdID。否则遇到第一个小于recd的得分,就更新recd和recdID。


如果在遍历完8种得分后,还没有满足上面两种情况的,则说明无解


最后只需打印recd的值即可。要注意float型变量相等的判断方法。


在UVa Board中,Brian Fry给了一个很好的提示:尝试不用float。一看得分的范围:10^3,两位小数,则可以果断的乘100得到一个范围为10^5的int。这样出错的机会又少了很多。最后除以100.0输出即可



Run Time: 0.172s

#define UVa  "8-8.1612.cpp" //Guess
char fileIn[30] = UVa, fileOut[30] = UVa;

#include<cstring>
#include<cstdio>
#include<vector>
#include<cmath>
#include<algorithm>

using namespace std;

void calc_scores(vector<int>& v, int* a, int d, int maxd, int sum) {    //get all 8 possibilities
    if(d == maxd)
        v.push_back(sum);
    else {
        calc_scores(v, a, d+1, maxd, sum+a[d]);
        calc_scores(v, a, d+1, maxd, sum);
    }
}

struct Player{
    vector<int> scores;
    int ID;
    Player(){}
    Player(int* a, int id):ID(id){
        calc_scores(scores, a, 0, 3, 0);
        sort(scores.begin(), scores.end());
    }
};

//Global Variables. Reset upon Each Case!
const int maxn = 20000;
int n;
int rank[maxn];
/////

int main() {
    int kase = 1;
    while(scanf("%d", &n) && n) {
        memset(rank, -1, sizeof(rank));

        Player q[maxn];
        float data_fl[3];
        int data_int[3];
        for(int i = 0; i < n; i ++) {
            for(int j = 0; j < 3; j ++) {
                scanf("%f", &data_fl[j]);
                data_int[j] = (int)(round((data_fl[j] * 100.0)));
            }
            Player& p = q[i];
            p = Player(data_int, i);
        }
        for(int i = 0; i < n; i ++) scanf("%d", &rank[i]);

        int recd = 1000000;
        int recdID = -1;
        for(int i = 0; i < n; i ++) {
            Player& u = q[rank[i]-1];
            int ok = 0;
            for(int j = 7; j >= 0; j --) {      //from large to small
                if(u.scores[j] == recd && u.ID > recdID) {         //same score, larger ID.
                    recdID = u.ID;
                    ok = 1;
                    break;
                }
                else if(u.scores[j] < recd) {                                   //smaller score.
                    recd = u.scores[j];
                    recdID = u.ID;
                    ok = 1;
                    break;
                }
            }
            if(!ok) {
                recd = -1;
                break;
            }
        }
        if(recd == -1) printf("Case %d: No solution\n", kase++);
        else printf("Case %d: %.2f\n", kase++, recd/100.0);
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值