【发布时间】:2017-04-08 16:42:52
【问题描述】:
问题陈述:
输入:
前两个输入是整数 n 和 m。 n 是在比赛中战斗的骑士数量(2
下一行包含 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)。我相信如果我更有效地从矢量中删除骑士,效率可以提高。使用集合擦除元素会更有效吗? IE。擦除连续片段而不是单个骑士。有没有更有效的替代方法?
#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");
}
}
【问题讨论】: