紫书 习题8-8 UVa 1612 (贪心+精度)

这道题我很快就写出来了, 但是一直WA, 然后发现是精度, 这坑了我一个小时……


(1)贪心。每次就尽量分数高, 可以保证最后分数最高

(2)神tm精度问题。记住判断大于小于和等于的时候要用EPS(1e-6)

a == b                  fabs(a-b) < EPS
a != b                  fabs(a-b) > EPS
a < b                   a + EPS < b
a <= b                   a - EPS < b
a > b                   b + EPS < a
a >= b                   b - EPS < a

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

const int MAXN = 21234;
const double EPS = 1e-6;
vector<double> score[MAXN];
int num[MAXN], n;

void add(int i, double x, double y, double z)
{
	score[i].clear();
	score[i].push_back(0);
	score[i].push_back(x); score[i].push_back(y);
	score[i].push_back(z); score[i].push_back(x+y);
	score[i].push_back(y+z); score[i].push_back(x+z);
	score[i].push_back(x+z+y);
	sort(score[i].begin(), score[i].end()); 
}

int main()
{
	int kase = 0;
	while(~scanf("%d", &n) && n)
	{
		REP(i, 0, n)
		{
			double x, y, z;
			scanf("%lf%lf%lf", &x, &y, &z);
			add(i, x, y, z);
		}
		
		REP(i, 0, n) scanf("%d", &num[i]), num[i]--;
		double ans = 2e9; 
		bool ok = true;
		
		REP(i, 0, n)
		{
			int x = num[i], pos = 0;
			while(pos < score[x].size() && score[x][pos] + EPS < ans) pos++;
			if((i == 0 || num[i] > num[i-1]) && pos < score[x].size() && fabs(score[x][pos] - ans ) < EPS) continue;
			if(pos - 1 < 0)  { ok = false; break; }
			ans = score[x][pos-1];
		}
		
		if(ok) printf("Case %d: %.2lf\n", ++kase, ans);
		else printf("Case %d: No solution\n", ++kase);
	}
	
	return 0;
}


猜你喜欢

转载自blog.csdn.net/qq_34416123/article/details/80208606