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<bits/stdc++.h>
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<bits/stdc++.h>
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
*/