问题陈述:如何从矢量或集合中更有效地清除元素?
输入:
前两个输入整数n和m。 n是在比赛中战斗的骑士的数量(2 < = n < = 100000,1 < = m < = n-1)。 m是将要发生的战斗次数。
下一行包含n个功率级别。
接下来的m行包含两个整数l和r,表示骑士在第i场战斗中的位置范围。
每场战斗之后,除了最高等级之外的所有夜晚都将被淘汰。
每场战斗的范围是根据骑士的新位置而非原始位置给出的。
输出:
输出m条线,将含有从战斗骑士的原来的位置(索引)的第i行。每一行都是按升序排列。
样品输入:
8 4
1 0 5 6 2 3 7 4
1 3
2 4
1 3
0 1
样本输出:
1 2
4 5
3 7
0
下面是该过程的可视化。
1 2
[(1,0),(0,1),(5,2),(6,3),(2,4),(3,5),(7,6),(4,7)]
-----------------
4 5
[(1,0),(6,3),(2,4),(3,5),(7,6),(4,7)]
-----------------
3 7
[(1,0),(6,3),(7,6),(4,7)]
-----------------
0
[(1,0),(7,6)]
-----------
[(7,6)]
我已经解决了这个问题。我的程序产生正确的输出,但是,它是O(n * m)= O(n^2)。我相信如果我从矢量中更有效地清除骑士,效率可以提高。使用集合擦除元素会更有效率吗?即擦除连续的部分,而不是单个骑士。有没有其他方法可以做到更高效?
#define INPUT1(x) scanf("%d", &x)
#define INPUT2(x, y) scanf("%d%d", &x, &y)
#define OUTPUT1(x) printf("%d\n", x);
int main(int argc, char const *argv[]) {
int n, m;
INPUT2(n, m);
vector< pair<int,int> > knights(n);
for (int i = 0; i < n; i++) {
int power;
INPUT(power);
knights[i] = make_pair(power, i);
}
while(m--) {
int l, r;
INPUT2(l, r);
int max_in_range = knights[l].first;
for (int i = l+1; i <= r; i++) if (knights[i].first > max_in_range) {
max_in_range = knights[i].first;
}
int offset = l;
int range = r-l+1;
while (range--) {
if (knights[offset].first != max_in_range) {
OUTPUT1(knights[offset].second));
knights.erase(knights.begin()+offset);
}
else offset++;
}
printf("\n");
}
}
能否请您阐述一下我怎么能做到这一点带套? – user6005857
http://www.cplusplus.com/reference/set/set/erase/ – seleciii44
是否有可能在O(nlogn)做这个问题?有没有可以有效地将新索引映射到旧索引的数据结构或算法? – user6005857