您的位置:首页 > 产品设计 > UI/UE

UVa 1612:Guess(贪心)

2015-08-23 19:53 399 查看
题目链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=845&page=show_problem&problem=4487

题意:有n(n≤16384)(n \le 16384)位选手参加编程比赛。比赛有3道题目,每个选手的每道题目都有一个评测之前的预得分(这个分数和选手提交程序的时间相关,提交的越早,预得分越大)。接下来是系统评测。如果某道题未通过测试,则改题的实际得分为0分,否则得分等于预得分。得分相同的选手,ID小的排在前面。

问是否能给出所有3n个得分以及最后的实际名次。如果可能,输出最后一名的最高可能得分。每个预得分均为小于1000的非负整数,最多保留两位小数。(本段摘自《算法竞赛入门经典(第2版)》)

分析:采用贪心策略,对于第一名很明显应该是3道题的分数加起来,对于后面的选手而言,应该使得得分尽量的高,如果ID比上一位的大的话,得分可以和上一名相同,否则得分应该严格小于上一位。如果过程中无法找到满足的分数则无解。处理时要注意浮点数精度的问题。

代码:

#include <iostream>
#include <fstream>
#include <cstring>
#include <vector>
#include <queue>
#include <cmath>
#include <algorithm>
#include <set>
#include <string>

using namespace std;

const int maxn = 17005;

int n, num, pos, C;
int r[maxn];
bool flag;
double tmp;
double x[5], a[maxn][10];

int main()
{
while (~scanf("%d", &n), n)
{
flag = true;
memset(a, 0, sizeof(a));
for (int i = 0; i < n; ++i)
{
scanf("%lf%lf%lf", &x[0], &x[1], &x[2]);
for (int j = 0; j < 8; ++j)
{
num = j;
pos = 0;
while (num)
{
if (num & 1)
a[i][j] += x[pos];
num >>= 1;
++pos;
}
}
sort(a[i], a[i] + 8);
}
for (int i = 0; i < n; ++i)
scanf("%d", &r[i]);
tmp = a[r[0] - 1][7];
for (int i = 1; i < n; ++i)
if (r[i] > r[i - 1])
{
for (int j = 7; j >= 0; --j)
if (a[r[i] - 1][j] <= tmp + 1e-6)
{
tmp = a[r[i] - 1][j];
break;
}
}
else
{
flag = false;
for (int j = 7; j >= 0; --j)
if (fabs(a[r[i] - 1][j] - tmp) < 1e-6)
continue;
else if (a[r[i] - 1][j] < tmp)
{
tmp = a[r[i] - 1][j];
flag = true;
break;
}
if (!flag)
break;
}
printf("Case %d: ", ++C);
if (flag)
printf("%.2lf\n", tmp);
else
printf("No solution\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: