题目1550:分糖果

题目1550:分糖果

时间限制:1秒
内存限制:32 兆
特殊判题:
提交:996
解决:234



 
题目描述:

给从左至右排好队的小朋友们分糖果,
要求:
1.每个小朋友都有一个得分,任意两个相邻的小朋友,得分较高的所得的糖果必须大于得分较低的,相等则不作要求。
2.每个小朋友至少获得一个糖果。
求,至少需要的糖果数。

输入:

输入包含多组测试数据,每组测试数据由一个整数n(1<=n<=100000)开头,接下去一行包含n个整数,代表每个小朋友的分数Si(1<=Si<=10000)。

输出:

对于每组测试数据,输出一个整数,代表至少需要的糖果数。

样例输入:
   3
   1 10 1
   3
   6 2 3
   2
   1 1
 
 
样例输出:
    4
    5
    2
 
 

 图的简单应用,用数组模拟图。注意RUNTIME_ERROR,即数组边界和栈溢出的问题。

#include<stdio.h>
const int left=0;
const int right=1;
int s[100005];
int f[100005][2];
int c[100005];
int n;
int refresh(int k)  //从i点向两边更新。如果用DFS容易栈溢出,RUNTIME_ERROR,尽量用while替代DFS。
{
    int i=k;
    while (f[i][left]==1)
    {
        if (c[i-1]<=c[i]) c[i-1]=c[i]+1;
        i=i-1;
    }
    i=k;
    while (f[i][right]==1)
    {
        if (c[i+1]<=c[i]) c[i+1]=c[i]+1;
        i=i+1;
    }
    return 0;
}
int main()
{
    while (scanf("%d",&n)!=EOF)
    {
        for (int i=0;i<n;i++)
        {
            f[i][left]=0;
            f[i][right]=0;
            c[i]=0;
        }
        for (int i=0;i<n;i++)
            scanf("%d",&s[i]);
        if (s[1]>s[0]) f[0][right]=1;//初始化f[i][left]表示i左边是否存在比它大的数,f[i][right]表示i右边是否存在比它大的数
        for (int i=1;i<n-1;i++)
        {
            if (s[i-1]>s[i]) f[i][left]=1;
            if (s[i+1]>s[i]) f[i][right]=1;
        }
        if (s[n-2]>s[n-1]) f[n-1][left]=1;
        if (f[1][left]==0)
        {
            c[0]=1; 
            refresh(0);
        }
        for (int i=1;i<n-1;i++)
            if (f[i-1][right]==0 && f[i+1][left]==0) 
            {
                c[i]=1;
                refresh(i);
            }
        if (f[n-2][right]==0) 
        {
            c[n-1]=1;
            refresh(n-1);
        }
        long sum=0;
        for (int i=0;i<n;i++)
            sum+=c[i];
        printf("%ld
",sum);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/Secontao/p/3613153.html