• Interview Street Challenges Candies


    链接:https://www.interviewstreet.com/challenges/dashboard/#problem/4fe12e4cbb829

    分析:可以把rating看成一个有升有降的数组,然后数组中存在三种区域(连续升、连续降、水平),区域的最小长度为1。举个例子,rating[] = [1, 2, 3, 3, 4, 2],则direction[] = [↑, ↑, 〓, ↑, ↓]。对于每个连续区间,都从1开始计数(连续升的,从1开始递增;连续降的看成从右向左的连续升,相等的始终为1),并且记录左右边界值。以前面例子,可以分成[1, 2, 3] {left = 1, right = 3}、[1, 1] {left = 1, right = 1}、[1, 2] {left = 1, right = 2}、[2, 1] {left = 2, right = 1}这几个区间。

          现在如何利用区间数据来计算Candies呢?

    section 1 2 3 1 2  
    section     1 1 2 1
    rating 1 2 3 3 4 2

    这样看来,只需在区间交错位置取最大值即可,其它直接累加区间值,最终结果就是Candies数。此例中Candies = 1 + 2 + 3 (max(3, 1)) + 1 (max(1, 1)) + 2 (max(2, 2)) + 1 =  1 + 2 + 3 + 1 + 2 + 1 = 10。

    代码(AC):

    #include <cstdio>
    #include <memory.h>
     
    using namespace std;
     
    int max(int a, int b)
    {
        return a > b ? a : b;
    }
     
    // Calculate the section candies without boundary value,
    // the boundary value will be set to left and right.
    int continual_section_candies(int *rating, int begin, int end, int *left, int *right)
    {
        int sum = 0;
     
        if (rating[begin] < rating[end])
        {
            *left = 1;
            *right = end - begin + 1;
            sum += (*left + *right) * (*right) / 2;
            sum -= *left;
            sum -= *right;
        }
        else if (rating[begin] > rating[end])
        {
            *right = 1;
            *left = end - begin + 1;
            sum += (*left + *right) * (*left) / 2;
            sum -= *left;
            sum -= *right;
        }
        else
        {
            sum += (end - begin - 1);
            *left = 1;
            *right = 1;
        }
     
        return sum;
    }
     
    int get_direction(int left, int right)
    {
        if (left < right)
            return 1;
     
        if (left > right)
            return -1;
     
        return 0;
    }
     
    int main(int argc, char **argv)
    {
        int rating[100005];
        int n = 0;
     
        // Get n.
        scanf("%d", &n);
     
        // Handle special case.
        if (n <= 0)
        {
            printf("0");
            return 0;
        }
        else if (n == 1)
        {
            printf("1");
            return 0;
        }
        
        // Init and read rating.
        memset(rating, 0, sizeof(rating));
        for (int i = 0; i < n; ++i)
        {
            scanf("%d", rating + i);
        }
     
        // Add a special value in rating end to 
        // make sure the rating end will be detected as a section end.
        rating[n] = rating[n - 1] == rating[n - 2] ?
            rating[n - 1] + 1 : rating[n - 2];
     
        // Update n.
        ++n;
     
        int candies = 0;                
        int last_inflection_pos = 0;   
        int last_inflection_value = 0;
     
        for (int i = 1; i < n - 1; ++i)
        {
            const int left_direction = get_direction(rating[i - 1], rating[i]);
            const int right_direction = get_direction(rating[i], rating[i + 1]);
     
            if (left_direction != right_direction)
            {
                int left, right;
                candies += continual_section_candies(rating, last_inflection_pos, i, &left, &right);
                candies += max(left, last_inflection_value);
                last_inflection_pos = i;
                last_inflection_value = right;
            }
        }
     
        candies += last_inflection_value;
     
        printf("%d", candies);
        return 0;
    }
         
  • 相关阅读:
    字符串操作函数5!!
    字符串操作函数4
    字符串操作函数3
    java开发命名规范总结
    centerOS网络NAT和桥接
    input框的内容变化监听
    Xunsearch迅搜项目实战经验
    PHP网络爬虫之CURL学习
    Xunsearch的使用总结
    Xshell 5 过期
  • 原文地址:https://www.cnblogs.com/codingmylife/p/2632279.html
Copyright © 2020-2023  润新知