问题描述
赛马场有 n 匹马,编号分别为 1,2,⋯,n。进行 m 次淘汰赛,决出他们当中速度最快的一匹马。每次淘汰赛所有编号在区间 [L,R] 并且没有被淘汰的马参加比赛,其中编号为 p 的马获胜,其他的马都被淘汰。 m 次淘汰赛之后,只有一匹马未被淘汰。求所有被淘汰的每一匹马是被哪一匹马淘汰的。
输入格式
第一行包含两个整数 n,m 。 接下来 mm 行每行包含三个整数 L,R,p 。
输出格式
输出一行,包含 n 个整数,两个整数之间使用空格分隔。分别表示第 i 个整数表示淘汰第 i 匹马的马的编号。如果第 i 匹马是最终的胜利者,则输出 0 。
一种解法
首先:看题后可以得出这道题直接简单的扫过一遍就行了, 但肯定没这么简单(滑稽)
然后:细细琢磨,怎么才能避免超时呢?突然灵光一现(老师讲解)=> 将区间[L, R]中L到p的所有点指向p,所有p到R的点指向R + 1。
这样:可以在之后的循环中减少工作量,直接跳到新的区间了
最后:AC!
#include <bits/stdc++.h>
using namespace std;
int main(){
int n, m;
cin >> n >> m;
int tiao[n+1];
memset(tiao, -1, sizeof(tiao));
int to[n + 1];//这就是用来指向新区间的数组
for(int i = 1;i <= n;i++){
to[i] = i;
}
while(m--){
int l, r, p;
cin >> l >> r >> p;
for(int i = l;i <= r;i++){
if(i == p){
continue;
}
if(tiao[i] == -1){
tiao[i] = p;
if(i < p){
to[i] = p;
}else if(i > p){
to[i] = r+1;
}
}else if(tiao[i] != -1){
i = to[i]-1;
}
}
}
for(int i = 1;i <= n;i++){
if(tiao[i] == -1){
cout << 0;
}else{
cout << tiao[i];
}
if(i != n){
cout << " ";
}
}
return 0;
}