浙江大学软件学院2020年保研上机模拟练习

  • 7-1.Standard Form of Polynomial (20分)
  • 7-2.Distance of Triples (25分)
  • 7-3. Partial School Ranking (25分)
  • 7-4. Shopping With Coupons (30分)

7-1.Standard Form of Polynomial (20分)


Input

3
-1 4 -1

output

-2 -7 -4

题目大意: 给定出n个数,让你计算(x-a1)(x-a2)(x-a3)……(x-an)展开为多项式后,x^i前的系数(i = 0, 1, ……,n-1)。

思路:由于n <= 10, 可以采用DFS或者状态压缩,这里我用的是状态压缩。

#include <bits/stdc++.h>
using namespace std;int main() {int n;cin >> n;vector<int>v(n);for (int i = 0; i < n; i++) {cin >> v[i];v[i] = -v[i];}int ans[15];for (int i = 1; i <= n; i++)ans[i] = 0;for (int i = 1; i < (1 << n); i++) {int cnt = 0;int now = 1;for (int k = 0; (1 << k) <= i; k++) {if (i & (1 << k)) {cnt++;now = now * v[k];}}ans[cnt] += now;}cout << ans[1];for (int i = 2; i <= n; i++) {printf(" %d", ans[i]);}
}

7-2.Distance of Triples (25分)


Input

4 4 6
0 9 -1 11
10 -25 11 -10
9 2 41 17 12 30

output

MinD(11, 11, 12) = 2

题目大意: 给出三组数, 要求从分别从三组数中各取一个元素a, b, c,使得|a-b| + |a - c| + |c - b|最小,如果不唯一,则取a,b,c最大;

思路:题目中每个数组的大小为10^4, 如果暴力去写,O(n ^3)的复杂度肯定超时。
优化方法:不妨设取出的三个元素a < b < c,如下图。 我们可以知道, |a - b| + |a - c| + |c - b|的值就是b到a的距离,加上b到c的距离再乘以2。故我们可以选一个数组, 枚举其中的元素作为中间值b,再去另外两个数组中寻找合适的小于等于b且最接近b的a,大于等于b且最接近b的c,即为答案。寻找a,c的过程可以使用二分查找,故先对三个数组进行排序,复杂度O(K * nlog n), K为常数。
PS:一开始没仔细看输出条件,导致后面改的时候变得很繁琐,还加了很多没有用的代码,懒得再改了。

#include <bits/stdc++.h>
using namespace std;int find(vector<int>c, int k) {int ans = -1e9;int l = 0, r = c.size() - 1;while (l <= r) {int mid = (l + r) / 2;if (c[mid] > k) r = mid - 1;else if (c[mid] <= k) {if (k - c[mid] < k - ans) ans = c[mid];l = mid + 1;}}return ans;
} // 二分找接近k,小于等于k的值,没找到返回-1e9;
int find_(vector<int>c, int k) {int ans = -1e9;int l = 0, r = c.size() - 1;while (l <= r) {int mid = (l + r) / 2;if (c[mid] >= k) {if (c[mid] - k < abs(k - ans)) {ans = c[mid];}r = mid - 1;}else if (c[mid] < k) {l = mid + 1;}}return ans;
} // 二分找最接近k,大于等于k的值,没找到返回-1e9
bool jud = false;vector<int>cmp(vector<int>& x, vector<int>& y) {if (x.size() != 4)return y;if (y.size() != 4)return x;if (x[3] < y[3])return x;if (y[3] < x[3])return y;if (x[0] > y[0])return x;if (y[0] > x[0])return y;if (x[1] > y[1])return x;return y;
}vector<int> solution(vector<int>a, vector<int>b, vector<int>c) {int mi = 1e9;vector<int>ans;for (int i = a.size() - 1; i >= 0; i--) {int now = a[i];int  x = find(b, a[i]);int y = find_(c, a[i]);if (x != -1e9 && y != -1e9) {now = 2 * (y - x);if (now < mi || (now == mi && a[i] + x + y > ans[0] + ans[1] + ans[2])) {jud = 1;mi = now;ans = { a[i], x, y, mi};}}x = find(c, a[i]);y = find_(b, a[i]);if (x != -1e9 && y != -1e9) {now = 2 * (y - x);if (now < mi ||(now == mi && a[i] + x + y > ans[0] + ans[1] + ans[2])) {mi = now;jud = 1;ans = { a[i], y, x, mi };}}}return ans;
}int main() {int a, b, c;cin >> a >> b >> c;vector<int>aa(a), bb(b), cc(c);for (int i = 0; i < a; i++)cin >> aa[i];for (int j = 0; j < b; j++)cin >> bb[j];for (int i = 0; i < c; i++)cin >> cc[i];sort(aa.begin(), aa.end());sort(bb.begin(), bb.end());sort(cc.begin(), cc.end());vector<int>x = solution(aa, bb, cc);vector<int>y = solution(bb, aa, cc);if (jud) {swap(y[0], y[1]);}vector<int>ans = cmp(x, y);jud = 0;vector<int>z = solution(cc, bb, aa);if (jud) {swap(z[0], z[2]);}ans = cmp(ans, z);printf("MinD(%d, %d, %d) = %d",ans[0], ans[1], ans[2],  ans[3]);
}

7-3. Partial School Ranking (25分)

Input

11
7456 3 7457 7458 7459 157
6666 3 5551 5552 7777 100
1234 3 5678 9012 0002 80
8888 0 340
2468 3 0001 0004 2222 110
7777 1 6666 57
3721 1 2333 30
9012 3 1236 1235 1234 10
1235 2 5678 9012 50
2222 4 1236 2468 6661 6662 16
2333 4 3721 6661 6662 6663 44

output

4
8888 1 340
0001 15 340
5551 4 157
7456 4 157

题目大意:

思路:并查集+map+结构体排序

#include <bits/stdc++.h>
using namespace std;map<int, int>root;
map<int, int>grade;
int ff(int x) {if (root.find(x) == root.end()) {root[x] = x;return x;}while (x != root[x])x = root[x];return x;
}struct Node {int  id,cnt,  val;
};bool cmp(Node a, Node b) {if (a.val != b.val)return a.val > b.val;if (a.cnt != b.cnt)return a.cnt < b.cnt;return a.id < b.id;
}int main() {int n;cin >> n;while (n--) {int a, k, g;cin >> a >> k;int c_a = a;a = ff(a);while (k--) {int t;cin >> t;t = ff(t);a = ff(a);if (a < t)root[t] = a;else root[a] = t;}cin >> g;grade[c_a] = g;}map<int, pair<int, int>>vv;for (auto it : root) {int tt = it.first;int g = 0;if (grade.find(tt) != grade.end())g = grade[tt];tt = ff(tt);if (vv.find(tt) == vv.end())vv[tt].first = 0, vv[tt].second = 0;vv[tt].first++;vv[tt].second += g;}vector<Node>ans;for (auto it : vv) {ans.push_back({ ff(it.first), it.second.first, it.second.second });}cout << ans.size() << endl;sort(ans.begin(), ans.end(), cmp);for (int i = 0; i < ans.size(); i++) {printf("%04d %d %d\n", ans[i].id, ans[i].cnt, ans[i].val);}
}

7-4. Shopping With Coupons (30分)

Input

4 30
12 20 15 10
9 6 8 7

output

8 2

题目大意: 给出n种商品的价格,n种优惠券以及你所有的钱D。每种优惠券对同一种商品只能用一次,且每次购买一个商品,只能用一张优惠券(不能同时使用多张)。求最多可以买多少个商品(每种商品可以重复购买),同时,剩下的最多的钱是多少。


思路 :对于每种商品,购买他的最低价格序列是确定的,即它的价格减去从高到低排列的代金券的价格。故可以维护一个大小为N的优先队列,代表每种商品的购买最低价格是多少。

先对商品和代金券分别排序(代金券从大到小排序),然后构造优先队列,队列的每个元素由三部分组成,分别如下。队列的优先级由第二部分的值即最低花费价格来确定。

  1. 这个商品的价格
  2. 购买这个商品最低花费的价格
  3. 用到第几张代金券

假设第 i 个商品价格为ai,第 j 张代金券价值为bj。

初始时队列中的每个元素为(ai, ai - b0,0)

维护过程:当我们所剩余的价格大于等于0的时候,拿出队列顶部的元素假设为(ai,ai - bj,j),这是我们当前花费最少的钱能购买到的商品,如果剩余的钱不能购买,直接跳出循环,否则的话弹出顶部元素,更新剩余的钱,计数器cnt++,同时将(ai, ai - b(j + 1),j+1)加入队列中。

细节

  1. 因为不能购买原价商品,即每次买商品必须使用代金券,所以当 j + 1 == n的时候代表代金券已经用完了就不需要再在加入队列了,
  2. 优先队列默认大根堆,所以改用bj - ai

复杂度分析:因为题干保证了商品价格一定是大于代金券的值的,所以每次我们剩余的钱最少会减少1,堆的维护为log(n),故时间复杂度最坏情况下为O(D log n),D为我们初始所拥有的钱,最大为10^6,应该不会超时。

#include <bits/stdc++.h>
using namespace std;int a[100005], b[100005];int main() {int n, m;scanf("%d %d", &n, &m);for (int i = 0; i < n; i++)scanf("%d", &a[i]);for (int i = 0; i < n; i++)scanf("%d", &b[i]);sort(a, a + n);sort(b, b + n, greater<int>()); priority_queue < pair<int, pair<int, int>>>q;for (int i = 0; i < n; i++) {q.push(make_pair(b[0] - a[i], make_pair(a[i], 0))); // 优先队列默认大根堆, 所以采用b[0] - a[i];}int cnt = 0;while (m >= 0 && !q.empty()) {int aa = q.top().second.first, bb = q.top().second.second + 1;int cc = q.top().first;q.pop();if (m + cc >= 0) {m += cc;cnt++;}else break;if (bb == n)continue;else q.push(make_pair(b[bb] - aa, make_pair(aa, bb)));}printf("%d %d", cnt, m);
}

最后总结: 好好学英语!

浙江大学软件学院2020年保研上机模拟练习相关推荐

  1. 浙江大学软件学院2020年保研上机模拟练习 7-4 Shopping With Coupons

    目录 解题思路演进过程 第一次程序 第二次程序 第三次程序 解题思路演进过程 首先是题目的理解上:有n个商品,n张优惠券,实际上能买的商品个数最多就是n*n,为啥呢,这题默认是买一个商品必须用一张券, ...

  2. 浙江大学软件学院2020年保研上机模拟练习 7-2 Distance of Triples

    思路一: 3个数组都按照小到大排序,设置3个指针,起始都在数组的末尾,如果1个指针向前移动1位可以让对应元素和另两个数组元素的距离之和减小,则移动它.如果某一回合三个指针都没动,就跳出循环. 非满分: ...

  3. 浙江大学软件学院2020年保研上机模拟练习 7-3 Partial School Ranking

    并查集的使用时注意: 1. 合并两个结点是 F[sa] = sb 而不是 sb = F[sa],想一下含义. 2. 给每个结点赋予其自身为父节点时,要先判断它的父节点是不是0,也许已经有了. 我把照片 ...

  4. 浙江大学软件学院2020年保研上机真题练习

    用浏览器打开html文件即可,需要源文件私聊

  5. 浙江大学计算机与软件学院2019年保研上机模拟练习 --- 凌宸1642

    浙江大学计算机与软件学院2019年保研上机模拟练习 - 凌宸1642 7-1 Happy Numbers (20 分) - 简单数学 A happy number is defined by the ...

  6. 浙江大学软件学院2020年保研真题Distance of Triples (25 分)

    时间限制:300 ms 内存限制:64 MB The distance of triples (三元组) (a,b,c) is defined as D(a,b,c)=∣a−b∣+∣b−c∣+∣c−a ...

  7. 浙江大学计算机学院保研率,浙江大学2020届保研率25.9%,主要保研本校、复旦、交大、北大...

    原标题:浙江大学2020届保研率25.9%,主要保研本校.复旦.交大.北大 推免大户是医学院.计算机.电工.信息学院等. 1.推免比例 根据浙江大学本科生院<浙江大学推荐2020年免试研究生公示 ...

  8. 2020计算机保研经历

    本文章未经本人允许,不得私自转载! 打个小广告: 我的 Github :https://github.com/WilliamWuLH 不定期更新 LeetCode 刷题 和 各种学习笔记.欢迎 ⭐St ...

  9. 东北大学计算机保研每年多少清华,东北大学2020届保研率13%,主要保研本校、天大、国科大、华东、东南大学...

    根据<东北大学关于做好2020年推荐优秀应届本科毕业生免试攻读研究生工作的通知><2020年推免生名单公示>: 2020年东北大学推免生共计963人. 其中普通名额926人,辅 ...

最新文章

  1. 超好用的简单的jquery tab选项卡切换代码(点击切换和导航栏滑过)
  2. ArcGIS字段计算器 Field Calculator错误
  3. Replace Nested Conditional with Guard Clauses(以卫语句取代嵌套条件表达式)
  4. 技术转管理?这些“坑”你要绕道走
  5. DataTable中Compute计算函数
  6. 推荐几个阿里、美团、腾讯大佬的公众号,一起学习!
  7. pcap文件提取后的dataframe,切分前向流与后向流
  8. 计算机审计风险背景,计算机环境下审计风险的特征与对策研究 毕业论文.doc
  9. lua 差值 日期_lua时间戳和日期转换及踩坑
  10. python---单元测试
  11. [转载] python bp神经网络 mnist_Python利用全连接神经网络求解MNIST问题详解
  12. (三) 初识XMAL
  13. 万里航行总舵手——业务测试架构的设计
  14. “云湖共生 • 数智未来”数据湖应用实践白皮书重磅发布
  15. 2019最新版Eclipse下载与安装
  16. 视频教程-VB程序设计入门基础-其他
  17. 如何取消服务器自动关机,XP系统怎么取消自动关机?
  18. 二极管和极性电容的正负测量
  19. (附源码课件)10款Java小游戏满足你各种需求
  20. 嵌入式系统和物联网中的软件安全

热门文章

  1. PC的ARM的安全启动
  2. 使用matlab对一维矩阵的数据进行滤波
  3. kali系统渗透window实现屏幕监控
  4. BigDecimal如何保留小数位
  5. ctfshow Nodejs
  6. 第六章 样本与抽样分布
  7. MySQL - SUM() OVER() 函数用法详解
  8. JavaScript设计模式浅析
  9. C++:将六个tif分色片写成bmp格式图片(8位深)
  10. 原码、补码的除法运算