日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

牛客网笔试真题 2021 阿里巴巴编程题(4星)题解(1-5)

發布時間:2024/3/26 编程问答 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 牛客网笔试真题 2021 阿里巴巴编程题(4星)题解(1-5) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

2021阿里巴巴校招筆試真題_Java工程師、C++工程師_牛客網

1.小強現在有n個物品,每個物品有x,y兩種屬性和.他想要從中挑出盡可能多的物品滿足以下條件:對于任意兩個物品 i 和?j ,滿足( i.x < j.x 且 i.y < j.y)或者(i.x > j.x 且 i.y > j.y).問最多能挑出多少物品.

解:將物品按照x從小到大排序,x相同則y從小到大排序,將題目轉變為,尋找y的最長遞增子序列,LIS。實現時用dp時間復雜度是n^2,會超時。用二分是nlogn可以過。

LIS:遍歷數組,維護一個【遞增的數組】。當a[i]大于數組的最后一個值則直接插入尾端,否則用二分查找該值插入的位置,取代第一個比他大的值。當遍歷結束后,該數組的長度即為最長遞增子序列的長度。(ps:該數組不一定是最長遞增子序列的解哦~)

#include<stdio.h> #include<string.h> #include<math.h> #include<iostream> #include<string> #include<algorithm> #include<map> #include<queue> #include<vector> using namespace std;int B[1000005],len; struct p {int x,y; }a[100005];int cmp(p u, p w) {if(u.x!=w.x)return u.x<w.x;elsereturn u.y>w.y; } int BiSearch(int *b,int len,int w) { int left=0,right=len-1; int mid; while(left <= right) { mid=left+(right-left)/2; if (b[mid]>w) right=mid-1; else if (b[mid]<w) left=mid+1; else return mid; } return left; } int LIS(int *array,int n) { len=1;B[0]=array[0]; int i,pos=0; for(i=1;i<n;i++) { if(array[i]>B[len-1]) { B[len]=array[i]; len++; } else { pos=BiSearch(B,len,array[i]);B[pos]=array[i]; } } return len; } // 最長遞增子序列 int main() {int t,n,i,j;scanf("%d",&t);while(t--){scanf("%d",&n);for(i=0;i<n;i++)scanf("%d",&a[i].x);for(i=0;i<n;i++)scanf("%d",&a[i].y);sort(a,a+n,cmp);int s[n];for(i=0;i<n;i++)s[i]=a[i].y;printf("%d\n",LIS(s,n));}}

2.小強發現當已知xy=B以及x+y=A時,能很輕易的算出的值.但小強想請你在已知?A和B的情況下,計算出x^n+y^n的值.因為這個結果可能很大,所以所有的運算都在模1e9+7下進行.

解:列出n項找遞推關系。

#include<stdio.h> long long mm = 1e9+7; long long p[100005]; int main() {int t,a,b,n,i,j; scanf("%d",&t);while(t--){scanf("%d%d%d",&a,&b,&n);p[0]=2,p[1]=a;for(i=2;i<=n;i++){p[i]=(a*p[i-1]%mm-b*p[i-2]%mm+mm)%mm;//printf("%d %d\n",i,p[i]);}printf("%lld\n",p[n]);} }

3.?小強現在n有個節點,他想請你幫他計算出有多少種不同的二叉樹滿足節點個數為且樹的高度不超過m的方案.因為答案很大,所以答案需要模上1e9+7后輸出.
樹的高度: 定義為所有葉子到根路徑上節點個數的最大值.

解:N個結點二叉樹的個數是卡特蘭數,計算方法可以用遞歸思想得到,但這題還要增加一個高度限制。因此用二維數組來做dp。

可參考:組合數學 卡特蘭數 解釋與應用_請賜教-CSDN博客

#include<stdio.h> long long dp[55][55]; long long mod = 1e9+7; int main() {int n,m,i,j,k;scanf("%d%d",&n,&m);for(i=0;i<=m;i++)dp[0][i]=1;for(i = 1; i <= n; i++) {for(j = 1; j <= m; j++) {for(k = 0; k < i; k++) {int aa = (dp[k][j-1] * dp[i-k-1][j-1])% mod;dp[i][j] += aa;dp[i][j] %= mod;}}}printf("%d\n",dp[n][m]); }

4.小強在玩一個走迷宮的游戲,他操控的人物現在位于迷宮的起點,他的目標是盡快的達到終點。每一次他可以選擇花費一個時間單位向上或者向下或者向左或者向右走一格,或是使用自己的對稱飛行器花費一個時間單位瞬移到關于當前自己點中心對稱的格子,且每一次移動的目的地不能存在障礙物。

具體來數說,設當前迷宮有n行m列,如果當前小強操控的人物位于點A ( x , y ),那么關于點A中心對稱的格子B ( x ′ , y ′ )滿足x + x ′ = n + 1且y + y ′ = m + 1。需要注意的是,對稱飛行器最多使用5次。

解:廣搜四個方向+飛行器,注意標記走過的路、飛行器的使用次數等,這題深搜會超時。

#include<stdio.h> #include<queue> #include<string> #include<algorithm> using namespace std; struct p{int x,y,c,t; //c飛行次數 }; int fx[4][2]={0,1,0,-1,1,0,-1,0}; int a[505][505]; int main() {int n,m,i,j,k;int sx,sy,ex,ey;int mintime = 1e8;char c;scanf("%d%d",&n,&m);for(i=1;i<=n;i++){ getchar();for(j=1;j<=m;j++){scanf("%c",&c);if(c=='.')a[i][j]=1;else if(c=='#')a[i][j]=-1;else if(c=='S')sx=i,sy=j;else if(c=='E')ex=i,ey=j,a[i][j]=1;}}queue<p> q;p start;start.x=sx;start.y=sy;start.c=5;start.t=0;q.push(start);a[sx][sy]=-1;while(!q.empty()){p now = q.front();//printf("now:%d %d %d %d\n",now.x,now.y,now.c,now.t);q.pop();if(now.x==ex&&now.y==ey){if(now.t<mintime)mintime=now.t;}for(i=0;i<4;i++){int nextx = now.x+fx[i][0];int nexty = now.y+fx[i][1];if(nextx>=1&&nextx<=n&&nexty>=1&&nexty<=m&&a[nextx][nexty]==1){//printf("next:%d %d %d %d\n",nextx,nexty,now.c,now.t+1);a[nextx][nexty]=-1;p next;next.x=nextx;next.y=nexty;next.c=now.c;next.t=now.t+1;q.push(next);}}if(now.c!=0){int nextx = n+1-now.x;int nexty = m+1-now.y;if(nextx>=1&&nextx<=n&&nexty>=1&&nexty<=m&&a[nextx][nexty]==1){//printf("fly:%d %d %d %d\n",nextx,nexty,now.c-1,now.t+1);a[nextx][nexty]=-1;p next;next.x=nextx;next.y=nexty;next.c=now.c-1;next.t=now.t+1;q.push(next);}}}if(mintime!=1e8)printf("%d\n",mintime);elseprintf("-1\n"); }

5.最近部門要選兩個員工去參加一個需要合作的知識競賽,每個員工均有一個推理能力值Ai,以及一個閱讀能力值Bi。如果選擇第i個人和第j個人去參加競賽,那么他們在閱讀方面所表現出的能力為X=(Bi+Bj)/2,他們在推理方面所表現出的能力為(Ai+Aj)/2。現在需要最大化他們表現較差一方面的能力,即讓min(X,Y) 盡可能大,問這個值最大是多少。

解:將員工的A,B能力值之差的絕對值k=|ai-bi|由小到大排序,那么較差的能力是A還是B肯定是由排在后面的員工決定的。(原理:先取a,b中較小者,假設b<a,則b和max(b)的組合一定是當前對該員工來說的最佳組合,且b是組合的弱項。因為b的最好結果b+max(b) <= a+最大b員工的a項。即a-b>=最大b員工的(b-a),即后者的k>前者的k,可對應排序結果)

遍歷排序好的結構體,將當前員工的較弱能力(A/B)跟【當前】(遍歷過程中記錄當前的最值)該項能力(A/B)的最大值相加得maxk,記錄全局得maxk即為解。

#include<stdio.h> #include<math.h> #include<queue> #include<string> #include<algorithm> using namespace std; struct node{int a,b,k; }p[200005]; int cmp(node u,node w) {if(u.k!=w.k)return u.k<w.k;if(u.a!=w.a)return u.a<w.a;elsereturn u.b<w.b; } int main() {int n,i,j,k;int maxa=-1,maxb=-1,maxk=-1;scanf("%d",&n);for(i=0;i<n;i++){scanf("%d%d",&p[i].a,&p[i].b);p[i].k=fabs(p[i].a-p[i].b);}sort(p,p+n,cmp);maxa=p[0].a;maxb=p[0].b;for(i=1;i<n;i++){if(p[i].a>p[i].b){if(p[i].b+maxb>maxk)maxk=p[i].b+maxb;}else{if(p[i].a+maxa>maxk)maxk=p[i].a+maxa;}if(p[i].a>maxa)maxa=p[i].a;if(p[i].b>maxb)maxb=p[i].b;}printf("%.1lf\n",maxk/2.0); }

總結

以上是生活随笔為你收集整理的牛客网笔试真题 2021 阿里巴巴编程题(4星)题解(1-5)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。