1.前置知识
2.题意
现有n个人,分为两队。他们从第一个开始,消灭所有编号与战力值均比他小的敌人。且有m次操作会在第个人操作后将前
个人的战力值加1.求最后剩下多少人。
3.解法
这道题模拟过于麻烦,但是由于它特殊的顺序,使得一个人后面有敌人战斗值大于它,它就一定会被消灭,不会出现敌人先被消灭了的情况。那么我们就不用管顺序,直接由后往前,找出最大战斗力来比较就行了。而m次操作也是从前往后按照顺序进行的,也不用管顺序。只需要处理出最终的无战斗状态,再遍历就行了。
4.时间复杂度
5.代码
#include<stdio.h>
#include<algorithm>
using namespace std;
int T;
int n, m;
int a[50005], b[50005], ch[50005];
int main()
{
scanf("%d", &T);
while (T--)
{
int max0 = -1e9, max1 = -1e9,ans = 0;
scanf("%d %d", &n, &m);
for (int i = 1; i <= n; i++)
{
scanf("%d %d", &a[i], &b[i]);
if (i == 1)ch[i] = b[i];
else ch[i] = b[i] - b[i - 1];
}
for (int i = 1; i <= m; i++)
{
int x;
scanf("%d", &x);
ch[1]++;
ch[x + 1]--;
}
for (int i = 1, tot = 0; i <= n; i++)
{
tot += ch[i];
b[i] = tot;
}
for (int i = n; i >= 1; i--)
{
if (a[i] == 0)
{
max0 = max(max0, b[i]);
if(b[i] < max1)ans++;
}
else
{
max1 = max(max1, b[i]);
if (b[i] < max0)ans++;
}
}
printf("%d\n", n - ans);
}
return 0;
} 


京公网安备 11010502036488号