2013阿里笔试题
2013阿里巴巴暑期實習筆試
答題說明:
1.答題時間90分鐘,請注意把握時間;
2.試題分為四個部分:單項選擇題(10題,20分)、不定向選擇題(4題,20分)、填空問答(5題,40分)、綜合體(1題,20分);
3.其他一些亂七八糟的考試說明。
一、單項選擇題
1.下列說法不正確的是:(D)
A.SATA硬盤的速度速度大約為500Mbps/s
B.讀取18XDVD光盤數據的速度為1Gbps
C.前兆以太網的數據讀取速度為1Gpbs
D.讀取DDR3內存數據的速度為100Gbps
解析:DVD的1x是1350KB,16x是21600KB,就算是21.6MB好了=160Mbps
?
這圖明顯說明是20GB/s=160Gbps;
感覺內存還沒有硬盤快呢
2.(D)不能用于Linux中的進程通信
A.共享內存
B.命名管道
C.信號量
D.臨界區
所謂的臨界區(critical section),實際上指的是一段代碼。選D;在《Windows核心編程第五版》中,對臨界區的解釋是:它是一小段代碼,它在執行之前需要獨占對一些共享資源的訪問權。這種方式可以讓多行代碼以“原子方式”來對資源進行操控。這里的原子方式,指的是代碼知道除了當前線程之外,沒有其他任何線程會同時訪問該資源。當然,系統仍然可以暫停當前線程去調度其他線程。但是,在當前線程離開臨界區之前,系統是不會去調度任何想要訪問同一資源的其他線程。
?
3.設在內存中有P1,P2,P3三道程序,并按照P1,P2,P3的優先級次序運行,其中內部計算和IO操作時間由下表給出(CPU計算和IO資源都只能同時由一個程序占用):
P1:計算60ms---》IO 80ms---》計算20ms
P2:計算120ms---》IO 40ms---》計算40ms
P3:計算40ms---》IO 80ms---》計算40ms
完成三道程序比單道運行節省的時間是(C)
A.80ms
B.120ms
C.160ms
D.200ms
4.兩個等價線程并發的執行下列程序,a為全局變量,初始為0,假設printf、++、--操作都是原子性的,則輸出不肯哪個是(A)
void foo() {
if(a <= 0) {
a++;
}
else {
a--;
}
printf("%d", a);
}
A.01
B.10
C.12
D.22
5.給定fun函數如下,那么fun(10)的輸出結果是(C)
int fun(int x) {
return (x==1) ? 1 : (x + fun(x-1));
}
A.0
B.10
C.55
D.3628800
6.在c++程序中,如果一個整型變量頻繁使用,最好將他定義為(D)
A.auto
B.extern
C.static
D.register
7.長為n的字符串中匹配長度為m的子串的復雜度為(B)
A.O(N)
B.O(M+N)
C.O(N+LOGM)
D.O(M+LOGN)
解析: KMP算法不懂
8.判斷一包含n個整數a[]中是否存在i、j、k滿足a[i] + a[j] = a[k]的時間復雜度為()
A.O(n3)
B.O(n2lgn)
C.O(n2)
D.O(nlgn)
解析:O(N2)的算法能想一大堆,雖然最終我選的C,比如說用hash的話,三維遍歷可以輕松編程二維遍歷,但是總感覺是不是應該有nlgn的算法。
9.三次射擊能中一次的概率是0.95,請問一次射擊能中的概率是多少?(A)
A.0.63
B.0.5
C.**
D.0.85
10.下列序排算法中最壞復雜度不是n(n-1)/2的是_(D)
A.快速序排 B.冒泡序排 C.直接插入序排 D.堆序排
二、不定向選擇題
1.阻塞、就緒、運行的三態轉換
2.一個棧的入棧數列為:1、2、3、4、5、6;下列哪個是可能的出棧順序。(選項不記得)
3.下列哪些代碼可以使得a和b交換數值。(選項不記得)
4.A和B晚上無聊就開始數星星。每次只能數K個(20<=k<=30)A和B輪流數。最后誰把星星數完誰就獲勝,那么當星星數量為多少時候A必勝?
A.2013 B.2886 C.4026 D......E.....(選項不記得)
三、填空問答題
1.給你一個整型數組A[N],完成一個小程序代碼(20行之內),使得A[N]逆向,即原數組為1,2,3,4,逆向之后為4,3,2,1
void revense(int * a,int n) {
}
2.自選調度方面的問題,題目很長,就是給你三個線程,分別采用先來先分配的策略和最短執行之間的調度策略,然后計算每個線程從提交到執行完成的時間。題目實在太長,還有幾個表格。考察的是操作系統里面作業調度算法先進先出和最短作業優先。
3.有個苦逼的上班族,他每天忘記定鬧鐘的概率為0.2,上班堵車的概率為0.5,如果他既沒定鬧鐘上班又堵車那他遲到的概率為1.0,如果他定了鬧鐘但是上班堵車那他遲到的概率為0.9,如果他沒定鬧鐘但是上班不堵車他遲到的概率為0.8,如果他既定了鬧鐘上班又不堵車那他遲到的概率為0.0,那么求出他在60天里上班遲到的期望。
4.戰報交流:戰場上不同的位置有N個戰士(n>4),每個戰士知道當前的一些戰況,現在需要這n個戰士通過通話交流,互相傳達自己知道的戰況信息,每次通話,可以讓通話的雙方知道對方的所有情報,設計算法,使用最少的通話次數,是的戰場上的n個士兵知道所有的戰況信息,不需要寫程序代碼,得出最少的通話次數。
(先一遍遍歷,然后在回去,)
?
5.有N個人,其中一個明星和n-1個群眾,群眾都認識明星,明星不認識任何群眾,群眾和群眾之間的認識關系不知道,現在如果你是機器人R2T2,你每次問一個人是否認識另外一個人的代價為O(1),試設計一種算法找出明星,并給出時間復雜度(沒有復雜度不得分)。
解答:這個問題等價于找未知序列數中的最小數,我們將reg這個函數等價為以下過程:,如果i認識j,記作i大于等于j,同樣j不一定大于等于i,滿足要求,i不認識j記作i
int finds(S,N)
{
int flag=0;//用于判定是否有明星,即當前最小數另外出現幾次
int temp=0;//存放最小數在S中的位置
for(i=1;i
{
if(!reg(S[i],S[temp])//如果temp標號的數小于i標號的數
{
temp=i;
flag=0;//更換懷疑對象(最小數)時,標記清零
}
elseif(reg(S[temp],S[i])//如果temp里存放的確實是唯一最小數是不會跑進這里來的
{
flag++; `
}
}
if(flag>0) return -1;//表示沒有明星,例如所有的數都相等
return temp;//返回明星在S中的位置
}
| int cha() { int i=1;j=N; while(i<=N) { ? if(know(i,j)) ?i++;//認識就問下一個人 else j--;//不認識就問是否認識前一個人; if(0==j) return I; break; } } |
| 思路就是:從第一個人開始問,是否認識最后一個人, 若認識,說明肯定不是明星,放棄他,去問第二個人; 若不認識,再問是否認識第n-1個人,若認識說明還不是明星;不認識繼續問是否認識第n-2個人; 當找到明星時,肯定把所有人問遍了,(設每個人不問自己),j此時為0; 跳出循環,返回明星的位置; ? 最快是第一個位置是明星,問了n-1次; 最差是最后一個是明星,而且剩余的人都互相認識,這樣就問了(n-1)*(n-1)次,最后一個肯定是明星了,不用再問。 這種方式跟明星位置和剩余人之間認識度有關。。。。。 |
?
四、綜合題
皇冠用戶倉庫開銷:有一個淘寶商戶,在某城市有n個倉庫,每個倉庫的儲貨量不同,現在要通過貨物運輸,將每次倉庫的儲貨量變成一致的,n個倉庫之間的運輸線路圍城一個圈,即1->2->3->4->...->n->1->...,貨物只能通過連接的倉庫運輸,設計最小的運送成本(運貨量*路程)達到淘寶商戶的要求,并寫出代碼。
?
思路:這個在各種online-judge平臺上都有答案,純粹的數學問題,
如圖,這是一個倉庫分布的模擬,假設從第i個倉庫向第i+1個倉庫轉移的物品為Pi個單位,其中Pi為負表示思是從i+1個倉庫轉移到第i個倉庫,第n個倉庫轉移到第一個倉庫即為Pn,設最后每個倉庫平均后的貨物為ave個單位,則有要最小化|P1|+|P2|+…+|Pi|+…+|Pn|
ave[i]=ave=A[i]-Pi+Pi-1//平均就是每個點收到(前一個節點發出)的和本節點發出的,加上本節點原有的
ave[1]=A[1]-P1+Pn//第一個節點的平均
然后設W[i]=ave[i]-A[i]=-Pi+Pi-1//每個節點發出和收到的差值
于是S[i]=W[1]+W[2]+….W[i]=Pn-Pi//所有前i個節點發出收到的差值之和
即Pi=Pn-S[i] ,所以問題歸結到最小化|Pn-S[1]|+|Pn-S[2]|+…+|Pn-S[n]|
所以Pn是S中位數的時候最小//pn是最后一個節點發給節點1的。
?
實現了但是出不來結果、、、
| #include <cstdlib> #include <iostream> #include <math.h> #include <algorithm> using namespace std; ? const int N=100;? //定義數組大小 int input[N];?? //輸入的每個倉庫原始的貨物量 int sum=0;????? //所有倉庫總貨物量 int s[N];?????? //前i個節點得到和發出只差的和==這個差就是原有-平均 int avg; int n; void sort(int data[],int len) { ???? for(int i=0;i<len;++i) ???? {?????? ????????????? for(int j=0;j<len-i;++j) ???????????? { ???????????????????? if(data[j]>data[j+1]) ???????????????????? data[j]=data[j]^data[j+1]; ???????????????????? data[j+1]=data[j]^data[j+1]; ???????????????????? data[j]=data[j]^data[j+1]; ???????????? } ???? } } int main(int argc, char *argv[]) { ??? ??? while(cin>>n) ??? {? //n個倉庫 ? ?????for(int i=1;i<=n;++i) ?????? { ??????? cin>>input[i]; ??????? sum=sum+input[i]; ??????? avg=sum/n;?? //平均值 ??????? } ??????? avg=sum/n; ??? } ??? for(int i=1;i<=n;++i) ??? { ??????????? s[i]=input[i]+s[i-1]-avg;//前i個節點的差值之和 ??? } ??? sort(s,5);//對數組值從小到大排序 ??? int mid=s[n/2];//取中值 ??? mid=abs(mid); ??? int res=0;? ??? for(int i=1;i<=n;++i) ??????? { ??????????????? res+=abs(mid-s[i]); ??????????????? } ??????????????? cout<<"最小代價是: "<< res; ??? system("PAUSE"); ??? return EXIT_SUCCESS; } |
總結
- 上一篇: ORACLE递归_ 树形遍历查询根节点、
- 下一篇: 操作主机 RID matser