欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

[贪心] UVa1612 猜名次(浮点数精度问题)

程序员文章站 2022-06-02 20:25:04
...

题目###[贪心] UVa1612 猜名次(浮点数精度问题)

思路

1.读题:本题的题目需要好好理解一下,刚开始给的是ID依次1~ n的得分,然后再给的是rank1~ rank n的ID,题目说的不是很清楚。
2.基本思路就是贪心。为了使后面选手的选择空间更大,rank靠前的选手因尽能力分高,这道题就仅此而已了。另外ID并列的情况也很容易分析,详情可以看代码。
3.本题要考虑浮点数精度的问题。比较明智的做法是,由于给的和输出的都是两位小数,所以输入时乘100,输出时除100。

代码

#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <functional>
#include <algorithm>
#define _for(i,a,b) for(int i = (a); i<(b); i++)
using namespace std;

const int maxn = 20000;
struct node {
    int t1, t2, t3, ID;
}A[maxn],B[maxn]; // B为原始输入,A为按rank排好序的 
int n;
int score(int last, int i) {
    if (i == 0) return A[i].t1 + A[i].t2 + A[i].t3;    // 避免出现负下标
    int temp[] = { A[i].t1 + A[i].t2 + A[i].t3, A[i].t1 + A[i].t2, A[i].t1 + A[i].t3,
        A[i].t2 + A[i].t3, A[i].t1, A[i].t2, A[i].t3, 0 };
    sort(temp, temp + 8, greater<int>() );   // sort降序排列的方法,不要忘了()
    if (A[i - 1].ID < A[i].ID) {
        _for(i, 0, 8) if (last >= temp[i]) return temp[i];
    }
    else {
        _for(i, 0, 8) if (last > temp[i]) return temp[i];
    }
    return -1;
}

int main() {
    int kase = 0;
    while (scanf("%d", &n) && n) {
        double f1, f2, f3;
        _for(i, 0, n) {
            scanf("%lf%lf%lf", &f1, &f2, &f3);
            B[i].t1 = round(f1 * 100.0);
            B[i].t2 = round(f2 * 100.0);
            B[i].t3 = round(f3 * 100.0);   // 对double读入的处理
            B[i].ID = i+1; 
        }
        int t;
        _for(i, 0, n){
            scanf("%d", &t);
            A[i] = B[t-1];
        }
        int last = 300000 + 100;
        _for(i, 0, n) {
            last = score(last, i);
            if (last == -1) break;
        }
        if (last == -1) printf("Case %d: No solution\n", ++kase);
        else printf("Case %d: %.2f\n",++kase,(double)last/100);
    }
    return 0;
}

码农小技巧

1.读入的浮点数往往有误差,比如9.53读成9.5299999999这种,这时候为了避免可以使用round函数,其功能是四舍五入。不过讲道理这种误差这么大的情况少见,所以只要记得遇到了可以用round就可以了。

相关标签: 贪心 精度