在一组数字中找到最小值或最大值的计数

时间:2018-10-11 12:06:21

标签: c algorithm maxima minima

  

用户在下一行输入n个要遵循的数据,然后   然后输入n个数字a1,a2,...,an。这些数字是一个   一些山。如果存在,则这些数字的集合为“ ACCEPTABLE”   只有一个最大值或最小值。例如“ 1 2 3 2 1”,只有一个   最大值为3。“ 1 2 3 4”也有一个最大值。但“ 1 10 9 8 7 6 5   6 7“是不可接受的,因为它有两个最大值(10和7)或两个   最小值(1和5)。

     

换句话说,当且仅当该集合位于以下其中一个中时,该集合才是可接受的   这种形式:

     

a1 <= a2 <= a3 ... <= ai> a(i + 1)> ...> an

     

     

a1> = a2> = a3 ...> = ai

我必须在判断系统中提交答案,该系统将使用未知的测试用例对其进行测试。 完全禁止使用任何类型的数组或向量。

我的解决方法是:

//C code.
#include <stdio.h>
#include <stdlib.h>

int main()
{
    int n,temp;
    scanf("%d",&n);
    if (n==1)
    {
        int l;
        scanf("%d",&l);
        printf("Yes");
    }
    else
{
    int a,b;
    int last;
    int changes =0;
    int dec =0 , inc =0; //flag: checking if the set is incremental or decremental till now
    scanf("%d %d",&a,&b);

    if (a>b)
    {
        dec=1;
    }
    else if (a<b)
    {
        inc = 1;
    }
    else
    {
        inc =1;
        dec = 1;
    }
    last = b;
    for (int i =2;i<n;i++)
    {

        scanf("%d",&temp);
        if (temp>last && dec==1)
        {
            inc = 1;
            dec= 0;
            changes++;
        }
        if (temp<last && inc==1)
        {
            inc =0;
            dec=1;
            changes++;
        }


if (!(inc==1 && dec==1) && temp == last)
        {
            changes++;
        }
    last = temp;
        last = temp;
    }
    if (changes <=1)
    {

        printf("Yes");
    }
    else
    {
        printf("No");
    }
}
    return 0;
}

它为问题中的示例提供了正确的答案,但在某些未知的测试用例上失败了。任何想法如何解决这个问题?谁能给我一个用这个代码无法解决的测试用例?

P.1: 我加了

if (!(inc==1 && dec==1) && temp == last)
    {
        changes++;
    }

它接受了一个失败的测试用例,但仍然存在一个。

P.2:

这是我的其他算法,在某些测试用例上失败了,但是法官接受了第一个失败的测试用例的答案:

    #include <stdio.h>
#include <stdlib.h>

int main()
{
    int n;
    int inc=0;
    int dec=0;
    int peak=0;
    int valley=0;
    int last = -1;
    int a;
    scanf("%d",&n);
    for (int i =0;i<n;i++)
    {
        if (last!=-1)
        {
            last =a;
        }
        scanf("%d",&a);
        if (last!=-1)
        {
            if (a>last)
            {
                if (!(inc==1))
                {
                    valley++;
                    inc =1;
                    dec=0;
                }
            }
            if (a<last)
            {
                if (!(dec==1))
                {
                    peak++;
                    dec=1;
                    inc =0;
                }
            }
        }
        last =0;


    }
    if (valley<=1 && peak<=1)
    {
        // printf("valley: %d , peak:%d",valley,peak);
        printf("Yes");
    }
    else
    {
        printf("No");
    }
    return 0;
}

P.3

新算法:

#include <stdio.h>
#include <stdlib.h>

int main()
{
    long long int n,temp;
    scanf("%lld",&n);
    if (n==1)
    {
        long long int l;
        scanf("%lld",&l);
        printf("Yes");
    }
    else
{
    long long int a,b;
    long long int last;
    long long int changes =0;
    int dec =0 , inc =0; //flag: checking if the set is incremental or decremental till now
    scanf("%lld %lld",&a,&b);

    if (a>b)
    {
        dec=1;
    }
    else if (a<b)
    {
        inc = 1;
    }
    else
    {
        inc =1;
        dec = 1;
    }
    last = b;
    for (long long int i =2;i<n;i++)
    {

        scanf("%lld",&temp);
        if (temp>last && dec==1)
        {
            inc = 1;
            dec= 0;
            changes++;
        }
        if (temp<last && inc==1)
        {
            inc =0;
            dec=1;
            changes++;
        }
        if (changes>=1 && temp == last)//new change
        {
            changes+=100;
        }//end of new change
        last = temp;
    }
    if (changes <=1)
    {

        printf("Yes");
    }
    else
    {
        printf("No");
    }
}
    return 0;
}

5 个答案:

答案 0 :(得分:3)

scanf("%d",l);应该为scanf("%d", &l);scanf需要变量的地址。

因此带有n == 1的测试用例失败了。

请始终查看编译器警告:https://ideone.com/MKq3WK

答案 1 :(得分:2)

“ 4 1 1 2 1”说“否”,但应该说“是”。该代码无法正确处理incdec最初均为1的情况。

此外,代码必须对序列的第一部分(直到观察到第一个方向变化)和第二个部分使用不同的标准。在第一部分中,平等是被允许的,不会引起任何失格或状态改变。在第二部分中,平等是取消资格。

笑话

我不应该这样做,但是有时候人们无法抗拒。以下应解决问题。不要使用它。

#include <stdio.h>

int main(void)
{
    int c, n, p, s;
    scanf("%d%d", &n, &c);

    #define Table   \
        {  1,  0,  3 }, \
        {  1,  1,  2 }, \
        { -1, -1,  2 }, \
        {  4,  3,  3 }, \
        {  4, -1, -1 }, \

    for (s = 0; 0 <= s && --n; s = (int [][3]) {Table} [s] [1+(p>c)-(p<c)])
        { p = c; scanf("%d", &c); }

    printf("%s\n", 0 <= s ? "Yes" : "No");
}

答案 2 :(得分:1)

在P.2解决方案中,可以接受“ 4 1 2 1 1”,但不能接受,因为1不大于1!

答案 3 :(得分:1)

我们必须检测不平等方向的变化,然后禁止进一步的变化。无论如何,只要元素相等,就无法在增长还是下降之间下定决心。

我将使用具有六个可能值的状态变量:

  • x:尚未输入任何元素;

  • 0:我们一无所知;

  • 1:我们在最初的筹款区域;

  • -1:我们正处于下降的初始阶段;

  • 2:我们已经进入最后加注部分;

  • -2:我们现在处于下降的最后一节。

考虑先前和当前的输入值,以下过渡适用:

State  x: -> 0 (unconditionally)
State  0: p < c ->  1, p > c -> -1
State  1: p > c -> -2
State -1: p < c ->  2
State  2: p >= c -> Fail
State -2: p <= c -> Fail

初始状态为x。如果我们从不失败,那么当输入已用尽时就假定成功。这可以通过一个简单的switch语句和两个静态变量来实现,以记住先前的值和状态来实现。

有关某个部分是否可以为空的规范尚不清楚,所以我将其保留不变。

Python概念验证:

Input= [1, 2, 3, 2, 1]
#Input= [1, 10, 9, 8, 7, 6, 5, 6, 7]
#Input= [1, 2, 3, 4]
#Input= [4, 1, 2, 1, 1]

def Process(c):
    global p, s

    if s == None:
        s= 0
    elif s == 0:
        if p < c:
            s= 1
        elif p > c:
            s= -1
    elif s == 1:
        if p > c:
            s= -2
    elif s == -1:
        if p < c:
            s= 2
    elif s == 2:
        if p >= c:
            exit(-1)
    elif s == -2:
        if p <= c:
            exit(-1)
    p= c

s= None
for c in Input:
    Process(c)

答案 4 :(得分:0)

法官最终接受了该密码。主要问题在于条件,有些数字等于111222。问题陈述是正确的,ai之后不是<=或> =。

C语言中的代码:

#include <stdio.h>
#include <stdlib.h>

int main()
{
    long long int n,temp;
    scanf("%lld",&n);
    if (n==1)
    {
        long long int l;
        scanf("%lld",&l);
        printf("Yes");
    }
    else
{
    long long int a,b;
    long long int last;
    int flag =1;
    long long int changes =0;
    int incr=0,decr=0;
    int equ=0;
    int dec =0 , inc =0; //flag: checking if the set is incremental or decremental till now
    scanf("%lld %lld",&a,&b);

    if (a>b)
    {
        dec=1;
    }
    else if (a<b)
    {
        inc = 1;
    }
    else
    {
        equ=1;
    }
    last = b;
    for (long long int i =2;i<n;i++)
    {

        scanf("%lld",&temp);
        if (temp > last && equ==1)
        {
            inc = 1;
            dec=0;
            equ=0;
        }
        else if (temp <last && equ==1)
        {
            inc = 0;
            dec = 1;
            equ= 0;
        }
       else if (temp>last && dec==1)
        {
            inc = 1;
            dec= 0;
            changes++;
            incr++;
        }
        else if (temp<last && inc==1)
        {
            inc =0;
            dec=1;
            changes++;
            decr++;
        }
        if (changes>=1 && temp == last && incr>=0 && decr >=0)
        {
            flag = 0;
            changes+=100;
        }
        last = temp;
    }
    if (changes <=1&& flag)
    {

        printf("Yes");
    }
    else
    {
        printf("No");
    }
}
    return 0;
}