问题陈述:
输入:
前两个输入是整数 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");
}
}