题目描述
当今世界英雄人物层出不穷,分分钟出一个英雄人物。Lester记录着每个英雄的出场顺序,一共有n个英雄,Lester为他们打分从1到n,第i个英雄打分为x[i],分数各不相同,分数越高实力越强。已知对这n个英雄的依次打分序列 {x[i]} 形成了1到n的一个排列。这n个英雄中的每一个都要知道一件事情:在自己之后最早出现比自己强的人是几号?如果没有比自己强的就算做n+1号。
输入输出格式
输入格式
输入文件heroes.in 输入第一行为正整数n,不超过200000。第二行为n个正整数,由空格隔开,是1到n的排列。
输出格式
输出文件heroes.out 输出一行包含n各正整数。
输入输出样例
输入样例#1:
4
2 1 4 3
输出样例#1:
3 3 5 5
【说明】2后面第一个比它大的数是4(第3个数);1后面第一个比它大的数是4(第3个数);4后面没有比它大的数,输出5;3后面没有比它大的数,输出5。
输入样例#2:
3
1 2 3
输出样例#2:
2 3 4
【说明】1后面第一个比它大的数是2(第2个数);2后面第一个比它大的数是3(第3个数);3后面没有比它大的数,输出4。
解析
0.暴力枚举
复杂度O(N 2 )
对于随机数据挺快的
因为很快就可能跳出循环
从左到右查看每个位置i
从i+1开始从左到右
依次查看每一个位置j
如果第一次发现x[j]>x[i]
ans[i]=j
对于i号位置答案就是j
跳出内层循环
0.1代码来咯~~~~
int n;
cin>>n;
for(int i=1;i<=n;i++)cin>>x[i];
x[n+1]=n+1;
for(int i=1;i<=n;i++)
for(int j=i+1;j<=n+1;j++)
if(x[j]>x[i]){
cout<<j<<" ";
break;
}
1.0建模元素分析
当输出要回答多个问题时,有两类常见问询
在线问询 一问一答
离线问询 审问犯人,微信聊天
可以看完问题
换顺序回答
做考卷做作业
此题问了n个问题,属于哪一类?
1.1离线问询+双链表删除
离线问询
可以看完问题
换顺序回答
挑选最简单的
问题是哪个
i=1 i=2 i=3 i=4 1=5 1=6
6 4 2 1 3 5
得1分的人,他的答案就是此时他贴身右边邻居位置
得1分的人确定后,得分2的人能否确定呢?
将得1分的人删除后 他的答案就是此时他贴身
分析得分2的人 右边邻居位置
将得2分的人删除后 他的答案就是此时他贴身
分析得分3的人 右边邻居位置
...... ...... ...... ...... ...... ......
1.2代码来咯
for(int i=1;i<=n;i++){
cin>>x[i];
p[x[i]]=i;
nxt[i]=i+1;
pre[i]=i-1;
}
for(int i=1;i<=n;i++){
ans[p[i]]=nxt[p[i]];
nxt[pre[p[i]]]=nxt[p[i]];
pre[nxt[p[i]]]=pre[p[i]];
}
for(int i=1;i<=n;i++)cout<<ans[i]<<" ";
1.3代码简化
for(int i=1;i<=n;i++){
cin>>x[i];
p[x[i]]=i;
nxt[i]=i+1;
pre[i]=i-1;
}
for(int i=1;i<=n;i++){
nxt[pre[p[i]]]=nxt[p[i]];
pre[nxt[p[i]]]=pre[p[i]];
}
for(int i=1;i<=n;i++)cout<<nxt[i]<<" ";