感受
本來我就是抱着增長經驗的想法投的阿里,投過簡歷後它會通知你參加在線評測(每個職位的評測時間都是固定的),我的算法基礎本身就不太好,所以這次肯定涼涼了,這裏簡單的記錄一下。
選擇題10道,時間限定爲30分鐘,附加題也就是編程題,有兩道,時間限定爲50分鐘
編程題1
題目
良好的內存管理是 App 性能和穩定性的基石,隨着用戶在 App 內的訪問路徑不斷加深,我們需要對用戶已訪問過的頁面進行銷燬以回收內存。
假設用戶已訪問的各個頁面內存佔用已知,同時我們規定銷燬某頁面後,其相鄰的兩個頁面不能被銷燬,例如三個頁面分別爲1,2,3,銷燬2以後,則1和3不能被銷燬。 請問可以回收的最大總內存是多少?
編譯器版本: gcc 4.8.4
請使用標準輸入輸出(stdin,stdout) ;請把所有程序寫在一個文件裏,勿使用已禁用圖形、文件、網絡、系統相關的頭文件和操作,如sys/stat.h , unistd.h , curl/curl.h , process.h
時間限制: 1S (C/C++以外的語言爲: 3 S) 內存限制: 64M (C/C++以外的語言爲: 576 M)
輸入:
第一行是正整數,表述已訪問的頁面數,
第二行是一個數組,表示各頁面的內存佔用
輸出:
輸出可以回收的最大總內存
輸入範例:
3
1 2 3
輸出範例:
4
部分代碼
#include <math.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include <limits.h>
#include <stdbool.h>
/** 請完成下面這個函數,實現題目要求的功能 **/
/** 當然,你也可以不按照這個模板來作答,完全按照自己的想法來 ^-^ **/
int maxFreeMemory(int pageMemory_size, int* pageMemory) {
}
int main() {
int res;
int _pageMemory_size = 0;
int _pageMemory_i;
scanf("%d\n", &_pageMemory_size);
int _pageMemory[_pageMemory_size];
for(_pageMemory_i = 0; _pageMemory_i < _pageMemory_size; _pageMemory_i++) {
int _pageMemory_item;
scanf("%d", &_pageMemory_item);
_pageMemory[_pageMemory_i] = _pageMemory_item;
}
res = maxFreeMemory(_pageMemory_size, _pageMemory);
printf("%d\n", res);
return 0;
}
我的答案(僅供參考)
本代碼已通過,時間以及內存均符合題目要求
#include <math.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include <limits.h>
#include <stdbool.h>
//遞歸計算
int max(int* b,int i,int size,int sum,int* pageMemory){
//出口
if(i>=size){
return sum;
}
//第一個頁面可以被回收
if(i==0){
//假設該頁面回收,計算此時的最大值爲tempValue1
b[i]=1;
int temp=sum+pageMemory[i];
int tempValue1=max(b,i+1,size,temp,pageMemory);
//假設不回收,計算此時的最大值爲temp2
b[i]=0;
int temp2=max(b,i+1,size,sum,pageMemory);
//找出最大值
if(tempValue1>=temp2) return tempValue1;
else return temp2;
}
//當上一個頁面被回收時
else if(b[i-1]==1){
//按照題目要求,此時的頁面不可以被回收
b[i]=0;
int temp2=max(b,i+1,size,sum,pageMemory);
return temp2;
}
//上一個頁面沒有被回收,所以該頁面可以在兩個狀態中任選
else{
//假設該頁面回收,計算此時的最大值爲tempValue1
b[i]=1;
int temp=sum+pageMemory[i];
int tempValue1=max(b,i+1,size,temp,pageMemory);
//假設不回收,計算此時的最大值爲temp2
b[i]=0;
int temp2=max(b,i+1,size,sum,pageMemory);
//找出最大值
if(tempValue1>=temp2)return tempValue1;
else return temp2;
}
}
/** 請完成下面這個函數,實現題目要求的功能 **/
/** 當然,你也可以不按照這個模板來作答,完全按照自己的想法來 ^-^ **/
int maxFreeMemory(int pageMemory_size, int* pageMemory) {
// printf("%d",pageMemory[0]);
int b[pageMemory_size];
for(int i=0;i<pageMemory_size;i++) b[i]=0;
int sum=0;
return max(b,0,pageMemory_size,sum,pageMemory);
}
int main() {
int res;
int _pageMemory_size = 0;
int _pageMemory_i;
scanf("%d\n", &_pageMemory_size);
int _pageMemory[_pageMemory_size];
for(_pageMemory_i = 0; _pageMemory_i < _pageMemory_size; _pageMemory_i++) {
int _pageMemory_item;
scanf("%d", &_pageMemory_item);
_pageMemory[_pageMemory_i] = _pageMemory_item;
}
res = maxFreeMemory(_pageMemory_size, _pageMemory);
printf("%d\n", res);
return 0;
}
編程題2
題目我沒有保留,所以我大概說一下題目
如圖,有這麼一個矩形區域,寬爲m,高爲n,在左下角的O點有一個小球,在下邊界與小球距離爲q的位置上有一個小旗k,小球沿着與左側某夾角的一條直線運動,當運動到上邊界時反彈,第一次與上邊界的交點與左側的距離爲p。當運動到下邊界時,如果在下邊界的落腳點與k不重合,那麼小球可以繼續反彈,如果在下邊界的落腳點與k重合,那麼輸出小球移動的次數(我的理解:小球從O到上邊界是一次移動,從上邊界到下邊界是一次移動),如果小球無法與k重合,輸出0,否則輸出移動的次數,m>p,m>q,並且小球在與k重合前碰到矩形區域的拐角處也輸出0
輸入:
m n p q
輸出:
移動次數
輸入範例:
5 5 1 2
輸出範例:
2
我的答案(有待改進)
這道題目其實比上一題目要簡單的多,但是因爲上一題目耗時有點多,這道題目我沒有做完,以下代碼在測試集上沒有完全通過,通過率僅爲42.9%左右,所以我的這個代碼還是存在問題的
#include <stdio.h>
//此代碼存在問題,在測試集上通過率爲42.9%
int main() {
int m,n,p,q;
scanf("%d %d %d %d",&m,&n,&p,&q);
int res=0;
if(m<=p||m<=q) res=0;
else{
int c=q/p;
if(c%2==1){
res=0;
}else{
res=c;
}
}
printf("%d\n",res);
return 0;
}