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; }