JZOJ 1277. 最高的奶牛

Description

  FJ有N(1 <= N <= 10,000)头奶牛,编号为1到N,站成一条直线。每头奶牛自己的身高(正整数,秘密未知),告诉你最高奶牛的身高H及位置I,同时告诉你R(0 <= R <= 10,000)组信息,每组信息由两个数ai,bi组成,表示奶牛ai可以看到奶牛bi,这就意味着奶牛bi的身高至少和奶牛ai的身高一样高,同时奶牛ai到奶牛bi之间的奶牛身高必须低于奶牛ai
  现在要你求出每头奶牛最高可能的高度,保证有解。

Input

  第1行输入4个空格隔开的整数N,I,H,R
  第2到R+1行,每行两个空格隔开的不同的整数A,B(1<=A,B<=N),表示奶牛A能看到奶牛B

Output

  第1到N行,每行一个整数表示每只奶牛最高可能的高度。

Sample Input

9 3 5 5
1 3
5 3
4 3
3 7
9 8

Sample Output

5
4
5
3
4
4
5
5
5

Hint

解释:如果奶牛A和奶牛B一样高,则可以出现A看到B,B又看到A的情况,如果奶牛A矮于奶牛B,则只可能出现奶牛A看到奶牛B,奶牛B不可能看到奶牛A。

Solution

  • 这题仔细分析,可以发现是一个贪心。

  • F[i] 表示第 i 头奶牛的高度,首先把每个 F[i] 都赋成最高高度。

  • 对于两头相望的奶牛 l,r ,它们之间的奶牛高度都要 -1 ,以满足要求。

  • 即:

    F[i]=F[i]1 (l+1ir1)

  • 由于区间不重叠,此方法正确性显然。

  • 由于赋值的次数不确定,可以不处理重复的区间,这样就不会超时了。

Code

#include<cstdio>
#include<algorithm>
using namespace std;
const int N=10001;
int tot;
int first[N],next[N],en[N];
int f[N];
inline int read()
{
    int X=0,w=1; char ch=0;
    while(ch<'0' || ch>'9') {if(ch=='-') w=-1;ch=getchar();}
    while(ch>='0' && ch<='9') X=(X<<3)+(X<<1)+ch-'0',ch=getchar();
    return X*w;
}
int main()
{
    int n=read(),s=read(),t=read(),m=read();
    for(int i=1;i<=n;i++) f[i]=t;
    while(m--)
    {
        int x=read(),y=read();
        if(x>y) swap(x,y);
        next[++tot]=first[x];
        first[x]=tot;
        en[tot]=y;
    }
    for(int i=1;i<=n;i++)
        for(int j=first[i],last=0;j;j=next[j])
            if(en[j]!=last)
            {
                for(int k=i+1;k<en[j];k++) f[k]--;
                last=en[j];
            }
    for(int i=1;i<=n;i++) printf("%d\n",f[i]);
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值