2018网易有道(内推笔试)— 塔、字符串、瞌睡、果园
1、调整塔的高度
输入描述:第一行两个数n,k (1 <= n <= 100, 0 <= k <= 1000)表示塔的数量以及最多操作的次数。第二行n个数,ai(1 <= ai <= 104)表示第i座塔的初始高度。
输出描述:第一行两个数s, m,表示最小的不稳定值和操作次数(m <= k)接下来m行,每行两个数x,y表示从第x座塔上取下一块立方体放到第y座塔上。
输入例子1:3 2 5 8 5
输出例子1:0 2 2 1 2 3
#include<iostream> #include<algorithm> #include<stdio.h> #include <vector> #include<string> #include<map> using namespace std; bool cmp(pair<int, int>& a, pair<int, int>& b) { // 开始没写这个 if,卡在 20% ,加上100% // 减的时候,先拿编号大的;加的时候,先拿编号小的 if (a.second == b.second) { return a.first > b.first; } return a.second > b.second; } int main() { int n, k; while (cin >> n >> k) { vector<pair<int, int>> nums; vector<pair<int, int>> res; for (int i = 0; i < n; ++i) { int temp; cin >> temp; nums.push_back(make_pair(i + 1, temp)); } for (int i = 0; i < k; ++i) { sort(nums.begin(), nums.end(), cmp); if (nums[0].second - nums[n - 1].second <= 1) break; nums[0].second--; nums[n - 1].second++; res.push_back(make_pair(nums[0].first, nums[n - 1].first)); } sort(nums.begin(), nums.end(), cmp); cout << nums[0].second - nums[n - 1].second << " " << res.size() << endl; for (int i = 0; i < res.size(); ++i) { cout << res[i].first << " " << res[i].second << endl; } } system("pause"); return 0; }
2、字符串排列
小易在学校中学习了关于字符串的理论, 于是他基于此完成了一个字典的项目。
小易的这个字典很奇特, 字典内的每个单词都包含n个'a'和m个'z', 并且所有单词按照字典序排列。
小易现在希望你能帮他找出第k个单词是什么。
输入描述:输入包括一行三个整数n, m, k(1 <= n, m <= 100, 1 <= k <= 109), 以空格分割。
输出描述:输出第k个字典中的字符串,如果无解,输出-1。
输入例子1:2 2 6
输出例子1:zzaa
例子说明1:字典中的字符串依次为aazz azaz azza zaaz zaza zzaa
#include<iostream> #include<algorithm> #include<stdio.h> #include <vector> #include<string> #include<map> #include <functional> // std::greater using namespace std; int main() { int n, m, k; cin >> n >> m >> k; vector<char> res; while (n && m) { long int count = 1; if (n - 1 > n - 1 + m) { cout << -1 << endl; return 0; } if (n - 1 == n - 1 + m) count = 1; else { for (int i = 0; i < n - 1; i++) {//计算组合总数 count *= n - 1 + m - i; count /= (i + 1); if (count > k) break;//防止越界。count>k就可以退出计算了 } } if (k <= count) {//如果k小于等于count,则表明首字符的确应为a res.push_back('a'); n--;//问题缩减为 n-1个a和m个z 中找第k大 } else { res.push_back('z'); m--;//问题缩减为 n个a和m-1个z 中找第k-count大 k -= count; } } //循环结束后,剩余子序列只存在"aa..aaa" 或 "zz..zzz"1种情况,因此k==1,否则代表不存在这么多情况,即不存在第k个词 if (k != 1) { cout << -1; return 0; } while (n--)res.push_back('a'); while (m--)res.push_back('z'); for (int i = 0; i < res.size(); i++) { cout << res[i]; } cout << endl; system("pause"); return 0; }
3、瞌睡
小易觉得高数课太无聊了,决定睡觉。不过他对课上的一些内容挺感兴趣,所以希望你在老师讲到有趣的部分的时候叫醒他一下。你知道了小易对一堂课每分钟知识点的感兴趣程度,并以分数量化,以及他在这堂课上每分钟是否会睡着,你可以叫醒他一次,这会使得他在接下来的k分钟内保持清醒。你需要选择一种方案最大化小易这堂课听到的知识点分值。
输出描述:
小易这堂课听到的知识点的最大兴趣值。
输入
6 3 1 3 5 2 5 4 1 1 0 1 0 0
输出:16
维持一个最大窗k,找到其中包含0对应的最小值。
#include<iostream> #include<algorithm> #include<stdio.h> #include <vector> #include<string> #include<map> #include <functional> // std::greater using namespace std; int main() { int n, k; cin >> n >> k; k = min(k, n); vector<int> interes(n); vector<int> awake(n); int res = 0; for (int i = 0; i < n; ++i) { cin >> interes[i]; } for (int i = 0; i < n; ++i) { cin >> awake[i]; if (awake[i] == 1) res += interes[i]; } int score = 0; for (int i = 0; i < k; ++i) { if (awake[i] == 0) score += interes[i]; } int max_score = score; for (int i = k; i < n; ++i) { if (awake[i] == 0) { score += interes[i]; } if (awake[i - k] == 0) score -= interes[i-k]; max_score = max(score, max_score); } cout << res+ max_score << endl; system("pause"); return 0; }
4、果园
输入描述:
第一行一个数n(1 <= n <= 105)。第二行n个数ai(1 <= ai <= 1000),表示从左往右数第i堆有多少苹果第三行一个数m(1 <= m <= 105),表示有m次询问。第四行m个数qi,表示小易希望知道第qi个苹果属于哪一堆。
输出描述:
m行,第i行输出第qi个苹果属于哪一堆。
输入
5 2 7 3 4 9 3 1 25 11
输出
1 5 3
#include<iostream> #include<algorithm> #include<stdio.h> #include <vector> #include<string> #include<map> #include <functional> // std::greater using namespace std; int main() { int n, m; cin >> n; vector<int> nums(n), sum(n); cin >> nums[0]; sum[0] = nums[0]; int temp = nums[0]; for (int i = 1; i < n; ++i) { cin >> nums[i]; sum[i] = sum[i - 1] + nums[i]; } cin >> m; vector<int> ques(m); for (int i = 0; i < m; ++i) cin >> ques[i]; int i = 0; while (i<m) { int low = 0, high = n; int res = 0; //二分查找,找到第一个大于该值的值 while (low < high) { int mid = (low + high) / 2; if (sum[mid] == ques[i]) { res = mid; break; } else if (sum[mid] < ques[i]) { res = mid + 1; low = mid + 1; } else { high = mid; } } cout << res+1 << endl; i++; } system("pause"); return 0; }