第一题:
n个人,每个人有一个对应的技能值s,现在要从n个人中选出p个人,使得他们的技能值相同。
显然,如果存在p个人的技能值是相同的,输出0就可以了。如果不存在,就要找出p个人,对他们进行训练,治他们的技能值相同。
训练一个小时,技能值增加1,只有一个教练,也就是只能同时训练一个 人。找出最佳的p个人的方案,输出最小的训练时间。
AC的代码:
#include <stdio.h> #include <stdlib.h> #include <algorithm> using namespace std; int s[100010]; // skill score long long int t[100010]; int e[100010]; int main() { int tg; scanf("%d", &tg); int n, p; int ca=1; while(tg--) { scanf("%d %d", &n, &p); s[0] = 0; for(int i=1; i<=n; i++) { scanf("%d", &s[i]); } sort(s+1, s+n+1); t[0] = 0; for(int i=1; i<=n; i++) { t[i] = t[i-1] + s[i]; } for(int i=p; i<=n; i++) { e[i] = t[i] - t[i-p]; } int ans = s[p]*p - e[p]; int cur; for(int i=p; i<=n; i++) { cur = s[i]*p - e[i]; if(cur < ans) ans = cur; } printf("Case #%d: %d\n", ca, ans); ca++; } return 0; }
第二题:
每次给你一个R*C的矩阵,矩阵的元素不是1就是0。1代表此处是一个邮局,0代表此处一个邮局,或者理解成是一个需要邮寄的用户。
我们最多可以在某个为0的节点上再建立一个邮局,要输出的是每种方案中所有的用户到最近邮局的曼哈顿距离的最大值的最小值。
显然,如果矩阵中都是1,都是邮局,输出0就可以了(家门口就是邮局)。如果矩阵中存在0,显然“最多可以建一次邮局”的机会必
须要用上,再多建立一个邮局,一定可以减小或者不变当前邮局布局下的曼哈顿的最大值中的最小值。
那这个邮局选择在那个0的位置呢?最直接的方法就是枚举,枚举每个是0的位置,因为R和C的最大值是250。
但我写的代码貌似没过较大的数据量的case。第一次参加kickstart,每台搞明白。
代码:
#include <stdio.h> #include <stdlib.h> #include <algorithm> #include <vector> #include <math.h> using namespace std; struct node { int x, y; int w; }cur; int main() { int tg; scanf("%d", &tg); int r, c; int man_dis; int ca=1; vector<node>que1; vector<node>que0; while(tg--) { que0.clear(); que1.clear(); scanf("%d %d", &r, &c); char q[300][300]; for(int i=1; i<=r; i++) { scanf("%s", q[i]); for(int j=0; j<c; j++) { cur.x = i; cur.y = j+1; if(q[i][j] == ‘1‘) { que1.push_back(cur); } else { que0.push_back(cur); } } } int ans1 = 0; for(int i=0; i<que0.size(); i++) { int cur, mm=r+c+1; for(int j=0; j<que1.size(); j++) { cur = abs(que0[i].x - que1[j].x) + abs(que0[i].y - que1[j].y); if(cur < mm) mm = cur; } que0[i].w = mm; if(mm > ans1) ans1 = mm; } // 找出所有普通节点的最小man距离, 找出这些距离里面的最大距离 if(que0.size() == 0) { // printf("Case #%d: 0\n", ca); ca++; } else { int ans2 = 0; int ans = r+c+1; for(int i=0; i<que0.size(); i++) { int x1 = que0[i].x; int y1 = que0[i].y; // 假设当前节点是邮局 更新最大的man距离 vector<int>mandis; mandis.clear(); for(int j=0; j<que0.size(); j++) { int x2 = que0[j].x; int y2 = que0[j].y; // int dis = abs(que0[i].x - que0[j].x) + abs(que0[i].y - que0[j].y); int dis = abs(x1 - x2) + abs(y1 - y2); if(dis < que0[j].w) { mandis.push_back(dis); } else { mandis.push_back(que0[j].w); } } ans2 = 0; for(int j=0; j<mandis.size(); j++) { if(i!=j && mandis[j] > ans2) ans2 = mandis[j]; } if(ans2 < ans) ans = ans2; } printf("Case #%d: %d\n", ca, ans); ca++; } } return 0; }
第三题:
n个座位,编号1---n,现在有q个预定,每次预定都是(L, R),如(1, 3)表示预定了1、2、3的位置。
由于每次的座位预定可能会存在重复的座位预定而导致冲突,现在让你通过一种算法来实现保证每个预定的人
都能分到相同数量的k个座位,并保证这个k是最大的。没想到好的算法,故没有提交。(不过小数据量的情况下
暴力应该好过。依次枚举每个座位,轮流分给有预定的人)。
没有代码!
原文地址:https://www.cnblogs.com/yspworld/p/10590377.html
时间: 2024-10-31 12:55:12