感受
本来我就是抱着增长经验的想法投的阿里,投过简历后它会通知你参加在线评测(每个职位的评测时间都是固定的),我的算法基础本身就不太好,所以这次肯定凉凉了,这里简单的记录一下。
选择题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;
}