這幾天做了下美團校招的一些套題。(只寫了編程,這兩天慢慢更新吧)
這套題還是蠻簡單的。。我暴力了好幾個都能過。一個小時多一點差不多能寫完。
試題鏈接:美團點評2020校招數據分析方向筆試題
4、棋子翻轉
題意:在4*4的棋盤上擺滿了黑白棋子,黑白兩色的位置和數目隨機其中左上角坐標為(1,1),右下角坐標為(4,4),現在依次有一些翻轉操作,要對一些給定支點坐標為中心的上下左右四個棋子的顏色進行翻轉,請計算出翻轉后的棋盤顏色。
題解:這題有點坑,輸入輸出數據類型都是字符串,我可能leetcode刷多了以為是vector然后一直報段錯誤。
我用了極其暴力的手法做了輸入的處理。。因為這個字符串是固定了長度的。。所以。。看代碼吧。
代碼:

1 #include<bits/stdc++.h> 2 using namespace std; 3 int mp[5][5]; 4 int pos[4][4]; 5 string s; 6 string p; 7 8 void init(){ 9 cin>>s; 10 cin>>p; 11 mp[0][0] = s[2]-'0'; 12 mp[0][1] = s[4]-'0'; 13 mp[0][2] = s[6]-'0'; 14 mp[0][3] = s[8]-'0'; 15 16 mp[1][0] = s[12]-'0'; 17 mp[1][1] = s[14]-'0'; 18 mp[1][2] = s[16]-'0'; 19 mp[1][3] = s[18]-'0'; 20 21 mp[2][0] = s[22]-'0'; 22 mp[2][1] = s[24]-'0'; 23 mp[2][2] = s[26]-'0'; 24 mp[2][3] = s[28]-'0'; 25 26 mp[3][0] = s[32]-'0'; 27 mp[3][1] = s[34]-'0'; 28 mp[3][2] = s[36]-'0'; 29 mp[3][3] = s[38]-'0'; 30 31 pos[0][0] = p[2]-'0'; 32 pos[0][1] = p[4]-'0'; 33 34 pos[1][0] = p[8]-'0'; 35 pos[1][1] = p[10]-'0'; 36 37 pos[2][0] = p[14]-'0'; 38 pos[2][1] = p[16]-'0'; 39 40 } 41 42 int main(){ 43 init(); 44 int x,y; 45 for(int i = 0; i < 3; i++){ 46 x = pos[i][0]; 47 y = pos[i][1]; 48 x--;y--; 49 if(x-1 >= 0) 50 mp[x-1][y] = !mp[x-1][y]; 51 if(x+1 < 4) 52 mp[x+1][y] = !mp[x+1][y]; 53 if(y-1 >= 0) 54 mp[x][y-1] = !mp[x][y-1]; 55 if(y+1 < 4) 56 mp[x][y+1] = !mp[x][y+1]; 57 } 58 cout<<"["; 59 for(int i = 0 ;i < 4;i++){ 60 cout<<"["; 61 for(int j = 0; j < 3 ;j++){ 62 cout<<mp[i][j]<<","; 63 } 64 if(i == 3) cout<<mp[i][3]<<"]"; 65 else cout<<mp[i][3]<<"],"; 66 } 67 cout<<"]"<<endl; 68 69 return 0; 70 }
5、尋找最后的山峰
題意:山峰元素是指其值大於或等於左右相鄰值的元素。給定一個輸入數組nums,任意兩個相鄰元素值不相等,數組可能包含多個山峰。找到索引最大的那個山峰元素並返回其索引。假設 nums[-1] = nums[n] = -∞。
題解:感覺也是一個模擬。。一次循環,判斷一下左右,滿不滿足條件。因為是找索引最大。。遍歷完就行了。
最后找一個特判,就是最后一個數是不是大於左邊的數就可以了。
優化當然也是可以,用二分可行。
代碼:

1 #include<bits/stdc++.h> 2 using namespace std; 3 4 vector<int> num; 5 int main(){ 6 int n; 7 while(cin>>n){ 8 num.push_back(n); 9 } 10 11 int len = num.size(); 12 int pos = 0; 13 for(int i = 1 ;i < len-1; i++){ 14 if(num[i]>=num[i+1] && num[i]>=num[i-1]){ 15 pos = i; 16 } 17 } 18 19 if(num[len-1] > num[len-2]) pos = len-1; 20 cout<<pos<<endl; 21 22 return 0; 23 }
6、比大小
題意:給定一個整數數組,返回一個數組。該返回數組中第i個數字為,原數組中第i個位置的數字至少往右走多少步才能遇到比它大的數字。如果遇不到或者已經處於最右的位置,則置為-1。
題解:這個題暴力是會超時的。做優化。參考了一下討論區大佬的代碼,用單調棧做處理。
這樣每次比較棧頂元素和當前元素,我們保存棧頂元素的這個步數就好了,也就是找棧頂的大元素。
友情提示:切c++14編譯器。
代碼:

1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn = 1e6+10; 4 5 int num[maxn]; 6 int ans[maxn]={0}; 7 int main(){ 8 int n; 9 cin>>n; 10 for(int i = 0; i < n ;i++){ 11 cin>>num[i]; 12 ans[i] = -1; 13 } 14 stack<int> s; 15 16 int cnt = 0; 17 while(cnt < n){ 18 if(!s.empty() && num[s.top()] < num[cnt]){ 19 int xx = s.top(); 20 s.pop(); 21 ans[xx] = cnt - xx; 22 } 23 else{ 24 s.push(cnt); 25 cnt++; 26 } 27 } 28 29 for(int i = 0; i < n ;i++){ 30 cout<<ans[i]<<endl; 31 } 32 33 return 0; 34 }
7、關聯查詢
題意:數據對象data1List,員工表,存儲員工ID,員工姓名
數據對象data2List, 員工工作時長表,存儲員工ID,月份,工時
計算每個員工1-3月每月工時及總工時
題解:我好像做復雜了。。就是一個模擬題。。我甚至懷疑只有一組數據。。理解題意就行了。
代碼:

1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn = 1010; 4 5 map<string,int> mp; 6 7 struct member{ 8 int id; 9 string name; 10 int sumtime; 11 }; 12 13 member peo[maxn]; 14 15 int main(){ 16 int cnt = 0; 17 while(cin>>peo[cnt].id>>peo[cnt].name){ 18 int id; 19 string month; 20 int time; 21 cin>>id; 22 for(int i = 0; i < 3; i++){ 23 cin>>month>>time; 24 mp[month] = time; 25 } 26 peo[cnt].sumtime = mp["01"]+mp["02"]+mp["03"]; 27 cout<<peo[cnt].name<<" "<<mp["01"]<<" "<<mp["02"]<<" "<<mp["03"]<<" "<<peo[cnt].sumtime<<endl; 28 cnt++; 29 } 30 31 32 return 0; 33 }
8、滑動窗口的中位數
題意:在實時計算中,數據流源源不斷地流入計算單元,經常需要借助窗口來處理數據,其中有一類窗口為滑動窗口(Sliding Window),其特點是窗口長度固定,每次滑動一定的位移(slide)
現給定一個數組 nums,有一個長度為 k 的滑動窗口從數組的最左側移動到數組的最右側。注意你只可以看到在滑動窗口 k 內的數字,滑動位移大小slide=1,即滑動窗口每次只向右移動一位。
要求返回每一個滑動窗口內的中位數,解釋中位數定義,例如:對於[2,3,4],中位數是3;對於[2,3],中位數是 (2 + 3) / 2 = 2.5
注意:為了簡化窗口計算,規定如果沒有累計到窗口大小的數,不能觸發計算,即不輸出結果!
題解:暴力可過。每次對窗口里的元素排序,得到中位數即可。
代碼:

1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn = 1010; 4 5 double num[maxn]; 6 vector<double> res; 7 int main(){ 8 int n,k; 9 cin>>n>>k; 10 for(int i = 0; i < n; i++){ 11 cin>>num[i]; 12 } 13 int flag = 0; 14 if(k%2) flag = 1; 15 16 for(int i = 0; i <= n-k; i++){ 17 for( int j = i; j < i+k ;j++){ 18 res.push_back(num[j]); 19 } 20 sort(res.begin(),res.end()); 21 22 if(flag) num[i] = res[k/2]; 23 else num[i] = (res[k/2 - 1] + res[k/2]) / 2; 24 25 res.clear(); 26 } 27 28 for(int i = 0; i <= n-k; i++){ 29 printf("%.1lf ",num[i]); 30 } 31 32 return 0; 33 }
9、月份天數
題意:輸入年份月份,請輸出這個月的天數
題解:也是個做了很多遍的題。判斷閏年。
閏年:1、能被4整除但是不能被100整除。2、能被400整除。
滿足以上條件隨便一個就行。
代碼:

1 #include<bits/stdc++.h> 2 using namespace std; 3 4 bool judge(int year){ 5 if(year%4 == 0 && year%100) return true; 6 if(year%400 == 0) return true; 7 8 return false; 9 } 10 11 int main(){ 12 int year,month; 13 while(cin>>year>>month){ 14 int flag = 0; 15 if(judge(year)) flag = 1; 16 if(month == 1 || month == 3 || month == 5 || month == 7|| 17 month == 8 || month == 10 || month == 12){ 18 cout<<31<<endl; 19 } 20 else if(month == 2){ 21 if(flag) cout<<29<<endl; 22 else cout<<28<<endl; 23 } 24 else cout<<30<<endl; 25 } 26 return 0; 27 }
10、整數分解
題意:一個正整數N可以分解為M(M>1)個正整數的和,即N=K+L,例如N=5、M=2時可以分解為(1+4,2+3)。
題解:整數分解也是比較經典的題目。一般我會先用dfs,再用dp。
= =牛客這個編譯器有毒,dfs得用c寫才行。要不然報段錯誤。dfs超時,dp應該是正解。
但是都不給AC。我看討論區也沒人過,應該題目有點問題。。
我會給出兩份代碼。
1、dfs。普通爆搜一定會超時,所以這里說的dfs是做了剪枝處理的。枚舉的時候從上一次的划分枚舉到sum+i*(m-cur)<=n,因為后面再繼續划分一定會大於當前所用分數。所以直接剪枝而不是枚舉到n。
2、dp。dp[i][j]表示i可以分成j份的方案。i中分j份可以為:i-1中分j-1份,和i-j中分j份。
初始化只需要做一個dp[0][0]=1。
代碼:

1 //深搜 2 #include<bits/stdc++.h> 3 using namespace std; 4 int n,m; 5 int cnt = 0; 6 7 8 void dfs(int res,int sum,int cur){ 9 if(cur == m){ 10 if(sum == n) cnt++; 11 return; 12 } 13 for(int i = res; sum+i*(m-cur)<=n ; i++){ 14 dfs(i,sum+i,cur+1); 15 } 16 17 } 18 int main(){ 19 cin>>n>>m; 20 dfs(1,0,0); 21 cout<<cnt<<endl; 22 23 24 return 0; 25 } 26 27 28 29 //dp 30 #include<bits/stdc++.h> 31 using namespace std; 32 const int maxn = 210; 33 int n,m; 34 int dp[maxn][maxn]={0}; 35 36 int main(){ 37 cin>>n>>m; 38 dp[0][0] = 1; 39 40 for(int i = 1; i <= n ;i++){ 41 for(int j = 1; j <= m ;j++){ 42 dp[i][j] += dp[i-1][j-1]; 43 if(i>=j) dp[i][j]+=dp[i-j][j]; 44 } 45 } 46 47 cout<<dp[n][m]<<endl; 48 49 return 0; 50 }