Desription
一个医生给n孩子拔牙,每个孩子有一个哭时的分贝大小v,哭声对其他孩子的影响数d以及自信度p,每当一个孩子拔牙之后,他的哭声会使其他的孩子失去信心,初始值为v,每经过一个人减少v-1,直至vi为0,如果其中有一个孩子的信心为负那么他会不拔牙跑了,他后面孩子的信心度都减去这个孩子的d值,问这个医生能给几个孩子拔牙,输出他们的编号
Input
第一行为一整数n表示孩子数,之后n行每行三个整数n,d,p表示孩子的三个特点值
Output
输出这个拔牙的孩子数以及这些孩子的编号
Sample Input
5
4 2 2
4 1 2
5 2 4
3 3 5
5 1 2
Sample Output
2
2 3
Solution
简单模拟,按照要求对每个孩子的p值更新即可,注意一点,如果一个孩子已经跑了,那么前面孩子的哭声造成的影响不会在这个孩子出减一而是传递给下一个还没跑的孩子,所以要用一个标记数组标记每个孩子是否跑掉,每次只对没有跑掉的孩子进行更新
Code
#include<stdio.h>
#include<string.h>
#define maxn 4001
typedef long long ll;
int n,vis[maxn],res,ans[maxn];
ll v[maxn],p[maxn],d[maxn];
int main()
{
while(~scanf("%d",&n))
{
memset(vis,0,sizeof(vis));//初始化标记数组
res=0;//拔牙的孩子数
for(int i=1;i<=n;i++)
scanf("%I64d%I64d%I64d",&v[i],&d[i],&p[i]);
for(int i=1;i<=n;i++)
{
if(vis[i])continue;//跑掉就不操作
ans[res++]=i;//每跑就拔牙
ll temp1=v[i],temp2=0;//temp1为拔牙孩子对后面孩子的影响,temp2为跑掉的孩子对后面孩子的影响
for(int j=i+1;j<=n;j++)
if(!vis[j])//哭声只对没跑的孩子有影响
{
p[j]-=temp1;
temp1--;
if(temp1<0)break;//影响结束
}
for(int j=i+1;j<=n;j++)
{
if(!vis[j])//孩子跑掉只对后面没跑的孩子有影响
p[j]-=temp2;
if(p[j]<0&&!vis[j])//又有孩子跑掉
{
temp2+=d[j];//影响扩大
vis[j]=1;//标记这个跑了的孩子
}
}
}
printf("%d\n",res);
for(int i=0;i<res;i++)
printf("%d%c",ans[i],i==res-1?'\n':' ');
}
return 0;
}