GTW likes gt
Accepts: 54
Submissions: 782
Time Limit: 2000/1000 MS (Java/Others)
Memory Limit: 131072/131072 K (Java/Others)
问题描述
从前,有n只萌萌的GT,他们分成了两组在一起玩游戏。他们会排列成一排,第i只GT会随机得到一个能力值bi。在第i秒的时候,第i只GT可以消灭掉所有排在他前面的和他不是同一组的且能力值小于他的GT。 为了使游戏更加有趣,GT的首领GTW会发功m次,第i次发功的时间为ci,则在第ci秒结束后,b1,b2,...,bci都会增加1。 现在,GTW想知道在第n秒之后,会有几只GT存活下来。
输入描述
第一行只有一个整数T(T≤5),表示测试数据组数。 第二行有两个整数n,m。表示GT的个数和GTW发功的次数。(1≤n≤50000,1≤m≤50000) 第三到n+2行,每行有两个整数ai,bi,表示第i只GT在哪个组和他的能力值 (0≤a[i]≤1,1≤b[i]≤106) 第n+3行到第n+m+2行,每行有一个整数ci,表示GTW第i次发功的时间。1≤c[i]≤n
输出描述
总共T行,第i行表示第i组数据中,GT存活的个数。
输入样例
1 4 3 0 3 1 2 0 3 1 1 1 3 4
输出样例
3
Hint
第1秒后 能力值为4 2 3 1 第2秒后 能力值为4 2 3 1 第3秒后 能力值为5 3 4 1,第2只GT被第3只GT消灭掉了 第4秒后 能力值为6 4 5 2 ci并不是有序的
这个题目的思路其实和Hackerrank上的这道题是一样的。https://www.hackerrank.com/challenges/stockmax
都是问这个数与之后比它大的数的影响的。可以从后往前面扫,记最大值,如果碰到比最大值小的,去掉即可。
代码:
#pragma warning(disable:4996)
#include <iostream>
#include <algorithm>
#include <cmath>
#include <vector>
#include <string>
#include <cstring>
#include <set>
#include <queue>
#include <stack>
#include <map>
#include <cstdio>
using namespace std;
typedef long long ll;
const int maxn = 50005;
struct no
{
int team;
int en;
}node[maxn];
int n, m;//GT的个数 GTW发功的次数
int c[maxn];//发功的时间
int pos[maxn];
void input()
{
int i, j;
memset(pos, 0, sizeof(pos));
scanf("%d%d", &n, &m);
for (i = 1; i <= n; i++)
{
scanf("%d%d", &node[i].team, &node[i].en);
node[i].team++;
}
for (i = 1; i <= m; i++)
{
scanf("%d", &c[i]);
pos[c[i]]++;
}
}
void solve()
{
int i;
int kill1 = -1;
int kill2 = -1;
int res = n;
for (i = n; i >= 1; i--)
{
kill1 = kill1 - pos[i];
kill2 = kill2 - pos[i];
if (node[i].team == 1)
{
if (kill2 > node[i].en)
{
res--;
}
kill1 = max(kill1, node[i].en);
}
else
{
if (kill1 > node[i].en)
{
res--;
}
kill2 = max(kill2, node[i].en);
}
}
cout << res << endl;
}
int main()
{
//freopen("i.txt", "r", stdin);
//freopen("o.txt", "w", stdout);
int t;
scanf("%d", &t);
while (t--)
{
input();
solve();
}
//system("pause");
return 0;
}