阿里笔试4.3场(附代码)+ 前6场代码链接
}隔几天做两道= =保持做题感觉
#阿里笔试##阿里巴巴##笔试题目##笔经# 前6场代码链接:
————————————————————————
第1题:对一个数组,求每个数左边比他大的数的最小值,右边比他小的数的最大值,若这两个数成倍数关系,记录。求被记录的总数量。
/*
对于每一位数据,每次进行一次查找操作和插入操作
首先从左向右遍历,查找比其大的左值中的最小值,再插入该值
再从右向左遍历,查找比其小的右值中的最大值,再插入该值
注意,如果该值为最大、最小值,则该值标记为无效
统计所有有效值里,左值整除右值的数量
时间复杂度O(nlogn),空间复杂度O(n)
*/
#include<iostream>
#include<vector>
using namespace std;
void insert(vector<long long> &sortlist, long long val) {
if(sortlist.empty()) {
sortlist.push_back(val);
}
int l = 0, r = int(sortlist.size())-1;
int mid;
while(l <= r) {
mid = (l+r)/2;
if(sortlist[mid] == val) {
return;
}
else if(sortlist[mid] > val){
r = mid-1;
}
else {
l = mid+1;
}
}
sortlist.insert(sortlist.begin()+l, val);
return;
}
long long valfind(vector<long long> &sortlist, long long val, bool findmin) {
if(sortlist.empty()) {
return val;
}
int l = 0, r = int(sortlist.size())-1;
int mid;
long long res = val;
if(findmin) {
while(l <= r) {
mid = (l+r)/2;
if(sortlist[mid] >= val) {
r = mid-1;
}
else {
res = sortlist[mid];
l = mid+1;
}
}
}
else {
while(l <= r) {
mid = (l+r)/2;
if(sortlist[mid] <= val) {
l = mid+1;
}
else {
res = sortlist[mid];
r = mid-1;
}
}
}
return res;
}
int countvalnum(vector<long long> &v) {
if(v.empty()) {
return 0;
}
int res = 0, i;
long long recmax[v.size()];
long long recmin[v.size()];
bool isvalid[v.size()];
vector<long long> sortlist;
for(i = 0; i < v.size(); i++) {
isvalid[i] = 1;
}
for(i = 0; i < v.size(); i++) {
recmax[i] = valfind(sortlist, v[i], 0);
if(recmax[i] == v[i]) {
isvalid[i] = 0;
}
insert(sortlist, v[i]);
}
sortlist.clear();
for(i = int(v.size()-1); i >= 0; i--) {
recmin[i] = valfind(sortlist, v[i], 1);
if(recmin[i] == v[i]) {
isvalid[i] = 0;
}
insert(sortlist, v[i]);
}
for(i = 1; i < v.size()-1; i++) {
if(isvalid[i] && recmax[i]%recmin[i] == 0) {
res++;
}
}
return res;
}
int main() {
int n;
cin>>n;
vector<long long> v;
int i, tmp;
for(i = 0; i < n; i++) {
cin>>tmp;
v.push_back(tmp);
}
cout<<countvalnum(v)<<endl;
return 0;
} 第2题:一个矩阵,每个元素代表经过其的代价。每一次可以上下左右方向走一步,求从最上行任意列,到最下行任意列的最小代价。 /*
bfs:先把第一行所有元素入队,每次判断队首元素上下左右方向上,如发现其路径比从当前队首位置到其更长,入队。
队列空则更新结束。
*/
#include<iostream>
#include<queue>
#include<vector>
#include<math.h>
using namespace std;
struct prs {
int x;
int y;
};
void update(queue<prs> &q, vector<vector<int> > &path, vector<vector<int> > &maze) {
prs tmp = q.front();
prs newtmp;
int nowdis = path[tmp.x][tmp.y] + maze[tmp.x][tmp.y];
if(tmp.x - 1 > 0 && path[tmp.x - 1][tmp.y] > nowdis) {
path[tmp.x - 1][tmp.y] = nowdis;
newtmp.x = tmp.x-1;
newtmp.y = tmp.y;
q.push(newtmp);
}
if(tmp.x + 1 < path.size() && path[tmp.x + 1][tmp.y] > nowdis) {
path[tmp.x + 1][tmp.y] = nowdis;
newtmp.x = tmp.x+1;
newtmp.y = tmp.y;
q.push(newtmp);
}
if(tmp.y - 1 > 0 && path[tmp.x][tmp.y - 1] > nowdis) {
path[tmp.x][tmp.y-1] = nowdis;
newtmp.x = tmp.x;
newtmp.y = tmp.y-1;
q.push(newtmp);
}
if(tmp.y + 1 < path[0].size() && path[tmp.x][tmp.y + 1] > nowdis) {
path[tmp.x][tmp.y+1] = nowdis;
newtmp.x = tmp.x;
newtmp.y = tmp.y+1;
q.push(newtmp);
}
q.pop();
return;
}
int minpath(vector<vector<int> > &maze) {
if(maze.empty() || maze[0].empty()) {
return 0;
}
vector<vector<int> > path;
vector<int> vtmp;
queue<prs> q;
prs tmp;
int res = INT_MAX;
int i,j;
for(j = 0; j < maze[0].size(); j++) {
vtmp.push_back(0);
tmp.x = 0;
tmp.y = j;
q.push(tmp);
}
path.push_back(vtmp);
vtmp.clear();
for(j = 0; j < maze[0].size(); j++) {
vtmp.push_back(INT_MAX);
}
for(i = 1; i < maze.size(); i++) {
path.push_back(vtmp);
}
while(!q.empty()) {
update(q, path, maze);
}
for(j = 0; j < maze[0].size(); j++) {
res = min(res, maze[maze.size()-1][j] + path[maze.size()-1][j]);
}
return res;
}
int main() {
int n, m;
cin>>n>>m;
int i,j;
vector<vector<int> > maze;
vector<int> vtmp;
int tmp;
for(i = 0; i < n; i++) {
for(j = 0; j < m; j++) {
cin>>tmp;
vtmp.push_back(tmp);
}
maze.push_back(vtmp);
vtmp.clear();
}
cout<<minpath(maze)<<endl;
return 0;
}
查看13道真题和解析