题目大意:有tol的工作量,和要求达到的工作剩余量sur,然后是公司总数,对应每个公司提供两种服务,1、完成一个工作量,2.完成当前未完成工作量的一半(注意这里是tol的一半,不是tol - sur的一半), 当剩余工作量为奇数, 对模2四舍五入。现在给出每个公司的两种服务所需费用, 要求计算出每个公司单独完成工作量所花费的最少金额(剩余工作量必须为sur,输出按照金额大小,相同按照公司名字的字典序大小。
解题思路:贪心, 对于每个公司,比较当前单位工作量的花费金额,来决定选用哪种服务。
#include <stdio.h> #include <string.h> #include <algorithm> using namespace std; const int N = 105; struct company { char name[N]; int one; int half; int value; }tmp[N]; char str[N]; int tol, sur; bool cmp(const company &a, const company &b) { if (a.value < b.value) return true; else if (a.value > b.value) return false; else return strcmp(a.name, b.name) < 0; } int count(int t, int h) { int sum = tol, cur = 0; while (sum != sur) { int w = (sum + 1) / 2; if (t * w > h && sum - w >= sur) { sum -= w; cur += h; } else { sum--; cur += t; } } return cur; } void handle(int cur) { int len = strlen(str), cnt = 0, sex = 0; for (int i = 0; i < len; i++) { if (sex == 0 && str[i] != ':') tmp[cur].name[cnt++] = str[i]; else if (str[i] == ':') { tmp[cur].name[cnt++] = '\0'; sex++; } else if (sex == 1 && str[i] != ',') tmp[cur].one = tmp[cur].one * 10 + str[i] - '0'; else if (str[i] == ',') sex++; else tmp[cur].half = tmp[cur].half * 10 + str[i] - '0'; } tmp[cur].value = count(tmp[cur].one, tmp[cur].half); } int main() { int cas, t = 1, n; scanf("%d", &cas); while (cas--) { memset(tmp, 0, sizeof(tmp)); scanf("%d%d%d%*c", &tol, &sur, &n); for (int i = 0; i < n; i++) { gets(str); handle(i); } sort(tmp, tmp + n, cmp); printf("Case %d\n", t++); for (int i = 0; i < n; i++) printf("%s %d\n", tmp[i].name, tmp[i].value); } return 0; }