#1620 : 股票价格3
时间限制:
10000ms
单点时限:
1000ms
内存限制:
256MB
-
5 69 73 68 81 82
样例输出
-
1 2 1 1 -1
描述
小Hi最近在关注股票,为了计算股票可能的盈利,他获取了一只股票最近N天的价格A1~AN。
小Hi想知道,对于第i天的股票价格Ai,几天之后股价会第一次超过Ai。
假设A=[69, 73, 68, 81, 82],则对于A1=69,1天之后的股票价格就超过了A1;对于A2=73,则是2天之后股票价格才超过A2。
输入
第一行包含一个整数N。
以下N行每行包含一个整数Ai。
对于50%的数据,1 ≤ N ≤ 1000
对于100%的数据,1 ≤ N ≤ 100000, 1 ≤ Ai ≤ 1000000
输出
输出N行,其中第i行代表对于第i天的股票价格Ai,几天之后股价会第一次超过Ai。
如果Ai+1~AN之内没有超过Ai,输出-1。
思路:题意也是很明确。直接模拟超时,就是要想个优化的方法。
我的思路是把每个价格绑定它对应的下标,然后按价格从小到大排序。
先把所有下标加到集合里面去,从价格低的开始遍历,先从集合取出当前价格对应的坐标,
然后二分查找大于当前数值对应下标的最小下标,就答案了。
注意:排序时价格相等时,下标从大到小排序,这样向后找到的比当前大的下标的价格也保证是比当前大的,
而不会出现相等的情况。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define INF 0x3f3f3f3f
#define FI first
#define SE second
int mod = 1000000007;
const int N = 101000;
struct Node
{
int v;
int id;
}rec[N];
int ans[N];
bool cmp(const Node &a, const Node &b)
{
if (a.v != b.v)
return a.v < b.v;
return a.id > b.id;
}
int main()
{
int n;
while (~scanf("%d", &n))
{
set<int> S;
for (int i = 0; i < n; i++)
{
int x;
scanf("%d", &x);
rec[i].v = x;
rec[i].id = i;
S.insert(i);
}
sort(rec, rec + n, cmp);
for (int i = 0; i < n; i++)
{
S.erase(rec[i].id);
//找大于当前下标的最小值下标
set<int>::iterator it = S.upper_bound(rec[i].id);
if (it == S.end())
{
ans[rec[i].id] = -1;
}else
{
ans[rec[i].id] = *it - rec[i].id;
}
}
for (int i = 0; i < n; i++)
printf("%d\n", ans[i]);
}
return 0;
}