(1)小易有一個古老的遊戲機,上面有着經典的遊戲俄羅斯方塊。由於它比較古老,因此規則和通常的俄羅斯方塊不一樣。
熒幕上一共有 n 列,每次都會有一個 1 x 1 的方塊隨機落下,在同一列中,後落下的方塊會疊在先前的方塊之上,當一整行方塊都被佔滿時,這一行會被消去,並獲得1分。
有一天,小易又開了一局遊戲,當玩到第 m 個方塊落下時他以爲太無聊就關掉了,小易但願你告訴他這局遊戲他得到的分數。ios
第一行兩個數 n, m
第二行 m 個數,c1, c2, ... , cm , ci 表示第 i 個方塊落在第幾列
其中 1 <= n, m <= 1000, 1 <= ci <= n
3 9 1 1 2 2 2 3 1 2 3
2
思路:咱們能夠記錄每一個位置上的個數,得分是各個位置的最小值。數組
#include <iostream> #include <vector> using namespace std; int main() { int n,m; cin>>n>>m; vector<int> game; game.resize(n+1,0); for(int i=0;i<m;i++) { int temp; cin>>temp; game[temp]++; } int min=1000; for(int i=1;i<game.size();i++) { min=min<game[i]?min:game[i]; } cout<<min<<endl; return 0; }
(2)小易以爲高數課太無聊了,決定睡覺。不過他對課上的一些內容挺感興趣,因此但願你在老師講到有趣的部分的時候叫醒他一下。你知道了小易對一堂課每分鐘知識點的感興趣程度,並以分數量化,以及他在這堂課上每分鐘是否會睡着,你能夠叫醒他一次,這會使得他在接下來的k分鐘內保持清醒。你須要選擇一種方案最大化小易這堂課聽到的知識點分值。 app
第一行 n, k (1 <= n, k <= 105) ,表示這堂課持續多少分鐘,以及叫醒小易一次使他可以保持清醒的時間。
第二行 n 個數,a1, a2, ... , an(1 <= ai <= 104) 表示小易對每分鐘知識點的感興趣評分。
第三行 n 個數,t1, t2, ... , tn 表示每分鐘小易是否清醒, 1表示清醒。
小易這堂課聽到的知識點的最大興趣值。
6 3 1 3 5 2 5 4 1 1 0 1 0 0
16
思路:最簡單的能夠暴力求解,獲得我在每一個時刻叫醒他所得到的興趣值,而後找到最大的。也有一種簡單點的。就是我先求出一開始他所獲得的興趣值,而後我再從前日後遍歷,判斷在各個時刻叫醒他,與一開始的興趣值,遍歷到最後也就找到了最大的興趣值。函數
#include <iostream> #include <vector> using namespace std; int main() { int n,k; cin>>n>>k; vector<int> a; a.resize(n,0); vector<int> t; t.resize(n,0); int sum=0; for(int i=0;i<n;i++) { cin>>a[i]; } for(int i=0;i<n;i++) { cin>>t[i]; sum+=a[i]*t[i]; } int max=sum; for(int i=0;i<=n-k;i++) { int temp=sum; for(int j=0;j<k;j++) { temp+=a[i+j]*(!t[i+j]);//取相反數,表明我叫醒,這樣也不會重複加上原本就醒的興趣值 max=max>temp?max:temp; } } cout<<max<<endl; }
(3)又到了豐收的季節,恰逢小易去牛牛的果園裏遊玩。
牛牛常說他對整個果園的每一個地方都瞭如指掌,小易不太相信,因此他想考考牛牛。
在果園裏有N堆蘋果,每堆蘋果的數量爲ai,小易但願知道從左往右數第x個蘋果是屬於哪一堆的。
牛牛以爲這個問題太簡單,因此但願你來替他回答。測試
第一行一個數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
思路:這道題很簡單,你們都會想到直接存儲每一堆的以前的蘋果總數,而後就很容易找到第Q個蘋果在哪堆。可是若是單純的找,因爲後面的測試用例很大,因此一次遍歷的複雜度過高,在搜索的過程當中咱們要用到二分搜索來下降遍歷的複雜度。spa
這裏用到的lower_bound的函數,它和upper_bound( )都是利用二分查找的方法在一個排好序的數組中進行查找的code
在從小到大的排序數組中,blog
lower_bound( begin,end,num):從數組的begin位置到end-1位置二分查找第一個大於或等於num的數字,找到返回該數字的地址,不存在則返回end。經過返回的地址減去起始地址begin,獲得找到數字在數組中的下標。排序
upper_bound( begin,end,num):從數組的begin位置到end-1位置二分查找第一個大於num的數字,找到返回該數字的地址,不存在則返回end。經過返回的地址減去起始地址begin,獲得找到數字在數組中的下標。遊戲
在從大到小的排序數組中,重載lower_bound()和upper_bound()
lower_bound( begin,end,num,greater<type>() ):從數組的begin位置到end-1位置二分查找第一個小於或等於num的數字,找到返回該數字的地址,不存在則返回end。經過返回的地址減去起始地址begin,獲得找到數字在數組中的下標。
upper_bound( begin,end,num,greater<type>() ):從數組的begin位置到end-1位置二分查找第一個小於num的數字,找到返回該數字的地址,不存在則返回end。經過返回的地址減去起始地址begin,獲得找到數字在數組中的下標。
#include <iostream> #include <vector> #include <algorithm> using namespace std; int main() { int n; cin>>n; vector<int> a; int apple=0; for(int i=0;i<n;i++) { int temp; cin>>temp; apple+=temp; a.push_back(apple); } int m; cin>>m; while(m--) { int t; cin>>t; int pos=lower_bound(a.begin(),a.end(),t)-a.begin()+1; cout<<pos<<endl; } return 0; }
(4)
#include <iostream> #include <vector> #include <set> using namespace std; int main() { int n,k; cin>>n>>k; vector<int> a; a.resize(n,0); for(int i=0;i<n;i++) { cin>>a[i]; } set<pair<int,int> > s; for(int i=0;i<n;i++) { s.insert(make_pair(a[i],i)); } vector<vector<int> > ans; while(k>0 && s.rbegin()->first-s.begin()->first>1 && s.size()>1) { set<pair<int,int> >::iterator f1=s.begin(); set<pair<int,int> >::reverse_iterator f2=s.rbegin(); pair<int,int> a = *f1; pair<int,int> b = *f2; s.erase(a); s.erase(b); a.first++; b.first--; vector<int> temp; temp.push_back(b.second+1); temp.push_back(a.second+1); ans.push_back(temp); k--; s.insert(a); s.insert(b); } cout<<(*s.rbegin()).first-(*s.begin()).first<<' '; cout<<ans.size()<<endl; for(int i=0;i<ans.size();i++) { for(int j=0;j<ans[i].size();j++) { cout<<ans[i][j]<<' '; } cout<<endl; } return 0; }