题目大意:给出n, m, L.n代表老板给的全部的paperworks的数量,m代表最终剩下的数量,L代表由这么多家公司需要你来计算最小的花费。
解题思路:
1、L家公司l行。每行由公司的名字 :A,B; A代表一份paperwork需要的money,B则代表帮你减少到总共的paperworks的数量一半要话费的money。注意这里是你手头上有的paperworks而不是老板要求你完成的数量,之前在这里卡了好久。还有减半不能导致最终的数量小于m。因为老板要求的是一定要剩下m份。
2、把输入的字符串分离出名字和钱A, B。
3、计算出金额排序输出。
代码:
#include <stdio.h> #include <algorithm> #include <string.h> using namespace std; const int N = 105; int n, m, l; struct MONEY { char name[N]; int money; int a, b; } M[N]; char str[N]; int cmp (const MONEY & x, const MONEY & y) { if (x.money < y.money) return true; else if (x.money > y.money) return false; else return strcmp (x.name, y.name) < 0 ? true: false; } //分离字符串 分离出名字和费用 void handle (int j) { int k = 0; for (int i = 0; i < strlen (str); i++) { if (str[i] != ':') k++; else break; } memcpy (M[j].name, str, sizeof (str)); M[j].name[k] = '\0'; int sum = 0; for (int i = k + 1; i < strlen (str); i++) { if (str[i] != ',') sum = sum * 10 + str[i] - '0'; else { M[j].a = sum; sum = 0; } } M[j].b = sum; } //计算费用 void cal (int j) { int num = n; int sum = 0; while (1) { if (num / 2 >= m && (num - num / 2 ) * M[j].a >= M[j].b) { sum += M[j].b; num /= 2; } else { sum += (num - m) * M[j].a; M[j].money = sum; break; } } } int main () { int t; char ch; scanf ("%d", &t); for (int i = 1; i <= t; i++) { printf ("Case %d\n", i); scanf ("%d%d%d%c", &n, &m, &l, &ch); for (int j = 0; j < l ; j++) { gets(str); handle(j); cal(j); } sort (M, M + l, cmp); for (int j = 0; j < l ; j++) printf ("%s %d\n", M[j].name, M[j].money); } return 0; }
uva:10670 - Work Reduction(贪心)
时间: 2024-10-13 04:06:49