题目大意:给出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;
}