阿里春招笔试2020.4.3(set/优队)

PS:该说啥,自己遇到这场竟然这么友好_(:з」∠)_

题目一(set)

小强和小明是很好的朋友,有一天小强在刷题的时候遇到一个他从来没有遇到过的问题,问题是这样描述的:
给你一个长度为 n n n的数组 a a a,问数组中有多少有价值的数?规定:若 a x a_x ax为有价值的数,当且仅当: x x x左侧存在大于 a x a_x ax的数,记左侧最小的大于 a x a_x ax的数 f f f,右侧小于 a x a_x ax的最大的数记为 g g g, f f f g g g的倍数。
数据范围 1 < = n < = 1 e 5 , 1 < = a i < = 1 e 18 1<=n<=1e5,1<=a_i<=1e18 1<=n<=1e5,1<=ai<=1e18
输入
整数 n n n和数组 a i a_i ai
输出
一个整数,表示数组中有价值的数的个数 。
思路:set

#include
using namespace std;
#define ll long long
const int maxn = 100010;

int n;
ll a[maxn];
ll l[maxn],r[maxn];
int main() {
	scanf("%d",&n);
	for(int i = 0;i < n;++i) {
		scanf("%lld",&a[i]);
		l[i] = r[i] = -1LL;
	}
	set<ll> st;
	set<ll>::iterator it;
	for(int i = 0;i < n;++i) {
		if(!st.empty() && (it = st.upper_bound(a[i])) != st.end()) 
			l[i] = *it;
		st.insert(a[i]);
	}
	st.clear();
	for(int i = n-1;i >= 0;--i) {
		if(!st.empty() && (it = st.upper_bound(-a[i])) != st.end()) 
			r[i] = -(*it);
		st.insert(-a[i]);
	}
	int ans = 0;
	for(int i = 0;i < n;++i) {
		if(l[i] != -1 && r[i] != -1 && (l[i]%r[i]==0))
			++ans;
	}
	printf("%d\n",ans);
	return 0;
}
/*
3
4 3 2

1 
*/ 

题目二(优队)
小强和小明有一天想去郊区玩,但是路上会经过一片山路。山路可以看作是一个 n n nx m m m 的网络,每个网络代表一个区域。山路崎岖不平,每个区域都有一个会消耗的体力值。
小强在走山路的时候,只能从一个区域走到相邻的4个(上下左右的网络)区域的任意一个。每到一个区域,会消耗对应的体力值。小强初始位置在第1行上方,需要到第n行下方
(可以在第1行任意区域作为起点,第n行任意区域作为终点)
小强想找一种走法,使得经过山路的总题理值消耗最小。请你帮小强找到这么一条路,并输出最小的总体力值消耗。
输入
数字n,m,代表山路的行和列。
接下来有n行,每行m个数字。第i行j列的数字 v i j v_{ij} vij,代表对应位置的区域的体力值。
其中 1 < = n , m < = 1000 , 0 < = v i j < = 1000 1<=n,m<=1000,0<=v_{ij}<=1000 1<=n,m<=1000,0<=vij<=1000
输出
一行一个数字表示所求的自小总体力值消耗。
思路:优队。

#include
using namespace std;
#define ll long long
const int maxn = 1010;

int n,m;
int a[maxn][maxn];
bool vis[maxn][maxn];
struct node{
	int x,y;
	int val;
	bool operator <(const node &a) const{
		return val > a.val;
	}
}cur,tmp;
int dx[]={0,0,1,-1};
int dy[]={1,-1,0,0};
bool check(int x,int y) {
	if(x<0 || x>=n || y<0 || y>=m) return 0;
	return 1;
}
int main() {
	scanf("%d%d",&n,&m);
	for(int i = 0;i < n;++i) {
		for(int j = 0;j < m;++j) {
			scanf("%d",&a[i][j]);
		}
	}
	priority_queue<node> q;
	for(int i = 0;i < m;++i) {
		cur.x = 0;cur.y = i;
		cur.val = a[0][i];
		q.push(cur);
		vis[0][i] = 1;
	}
	while(!q.empty()) {
		cur  = q.top();
		if(cur.x == n-1) {
			printf("%d\n",cur.val);
			return 0;
		}
		q.pop();
		int x,y;
		for(int i = 0;i < 4;++i) {
			tmp = cur;
			x = cur.x+dx[i];
			y = cur.y+dy[i];
			if(!check(x,y) || vis[x][y]) continue;
			tmp = cur;
			tmp.x = x;tmp.y = y;
			tmp.val += a[x][y];
			q.push(tmp);
			vis[x][y] = 1;
		}
	}
	printf("-1\n");//debug
}
/*
3 3 
3 1 3
3 1 0
3 1 3

3 

3 4
9 9 1 1
9 1 1 9
1 1 9 9

4 
*/ 

你可能感兴趣的:(笔试)