hdoj GTW likes gt 5596 (DP机智转换)好题

GTW likes gt

Accepts: 54
Submissions: 782
Time Limit: 2000/1000 MS (Java/Others)
Memory Limit: 131072/131072 K (Java/Others)
问题描述
从前,有nnn只萌萌的GT,他们分成了两组在一起玩游戏。他们会排列成一排,第iii只GT会随机得到一个能力值bib_ibi。在第iii秒的时候,第iii只GT可以消灭掉所有排在他前面的和他不是同一组的且能力值小于他的GT。
为了使游戏更加有趣,GT的首领GTW会发功mmm次,第iii次发功的时间为cic_ici,则在第cic_ici秒结束后,b1,b2,...,bcib_1,b_2,...,b_{c_i}b1,b2,...,bci都会增加1。
现在,GTW想知道在第nnn秒之后,会有几只GT存活下来。
输入描述
第一行只有一个整数T(T≤5)T(T\leq 5)T(T5),表示测试数据组数。
第二行有两个整数n,mn,mn,m。表示GT的个数和GTW发功的次数。(1≤n≤50000,1≤m≤500001\leq n \leq 50000,1\leq m\leq 500001n50000,1m50000)
第三到n+2n+2n+2行,每行有两个整数ai,bia_i,b_iai,bi,表示第iii只GT在哪个组和他的能力值 (0≤a[i]≤1,1≤b[i]≤106)(0\leq a[i]\leq 1,1\leq b[i]\leq 10^6)(0a[i]1,1b[i]106)n+3n+3n+3行到第n+m+2n+m+2n+m+2行,每行有一个整数cic_ici,表示GTW第iii次发功的时间。1≤c[i]≤n1\leq c[i]\leq n1c[i]n
输出描述
总共TTT行,第iii行表示第iii组数据中,GT存活的个数。
输入样例
1
4 3
0 3
1 2
0 3
1 1
1
3
4
输出样例
3
Hint
111秒后 能力值为4 2 3 14\ 2\ 3\ 14 2 3 1222秒后 能力值为4 2 3 14\ 2\ 3\ 14 2 3 1333秒后 能力值为5 3 4 15\ 3\ 4\ 15 3 4 1,第222只GT被第333只GT消灭掉了
第444秒后 能力值为6 4 5 26\ 4\ 5\ 26 4 5 2
cic_ici并不是有序的
 
#include<stdio.h>
#include<string.h>
#include<algorithm>
#define N 100010
using namespace std;
int a[N];
struct zz
{
	int zy;
	int nn;
}q[N];
int main()
{
	int t;
	int n,m;
	scanf("%d",&t);
	while(t--)
	{
		scanf("%d%d",&n,&m);
		for(int i=1;i<=n;i++)
			scanf("%d%d",&q[i].zy,&q[i].nn);
		memset(a,0,sizeof(a));
		for(int i=1;i<=m;i++)
		{
			int x;
			scanf("%d",&x);
			a[x]++;
		}
		for(int i=1;i<=n;i++)
			a[i]+=a[i-1];
		int mm0=-0x3f3f3f;
		int mm1=mm0;
		int cnt=n;
		for(int i=n;i>=1;i--)
		{
			int mm=q[i].zy;
			if(mm)
			{
				if(q[i].nn-a[i-1]<mm0)
					cnt--;
				mm1=max(mm1,q[i].nn-a[i-1]);
			}
			else
			{
				if(q[i].nn-a[i-1]<mm1)
					cnt--;
				mm0=max(mm0,q[i].nn-a[i-1]);
			}
		}
		printf("%d\n",cnt);
	}
	return 0;
}
//刚开始这样写的,果断超时。。
#include<stdio.h>
#include<string.h>
#include<algorithm>
#define N 50010
#define INF 0x3f3f3f3f
using namespace std;
int b[N];
int vis[N];
struct zz
{
	int zy;
	int nl;
}q[N<<1],mm;
int main()
{
	int t,n,m;
	int i,j;
	int x,y,c;
	scanf("%d",&t);
	while(t--)
	{
		memset(vis,0,sizeof(vis));
		memset(b,0,sizeof(b));
		scanf("%d%d",&n,&m);
		for(i=1;i<=n;i++)
			scanf("%d%d",&q[i].zy,&q[i].nl);
		for(i=1;i<=m;i++)
		{
			scanf("%d",&b[i]);
			vis[b[i]]=1;
		}
		int cnt=n;
		for(i=1;i<=n;i++)
		{
			if(q[i].nl!=INF)
			{
				mm=q[i];
				for(j=1;j<i;j++)
				{
					if(q[j].nl!=INF)
					{
						if(q[j].zy!=mm.zy&&q[j].nl<mm.nl)
						{
							cnt--;
							q[j].nl=INF;
						}
					}
				}
				if(vis[i])
					for(j=1;j<=i;j++)
						q[j].nl++;
			}
		}
		printf("%d\n",cnt);
	}
	return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值