UVa #1612 Guess (习题8-8)

86 篇文章 0 订阅

因为一共只有三道题,所以每个人的得分最多有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;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值