数字游戏 2020蓝桥杯A组模拟赛

小明开始玩起来了数字游戏,他一下子报出了一堆整数,并在报数过程中不断询问在这个数组里,有多少个子区间的积大于 0、等于 0、小于 0 。
输入格式: 输入第一行包括两个整数 n,m,表示小明已近报出的数的数量和后续询问的次数。 第二行包括 n个整数 ,表示小明已经报出的数。 接下来 m行,每行先输入一个整数 op,表示小明的操作: op=1 表示小明要再报一些数,首先会再输入 t,表示报的数的数量,接下来 t个数表示他依次报的数。 op=2 表示小明询问在已经报的数形成的数组里有多少个子区间的积大于 0、等于 0、小于 0。 数据保证至少有一次 op=2的操作。
输出格式:对于每组数据,输出一行一个整数表示答案。

思路:
1:出现零,则零后面的数乘以前面所得的积都是零。所以本题在输入的过程中我们只需记录最后一个零的位置,以及之后一个零以后所有正数、负数子区间的数量即可。
2:如果输入的数是一个正数,则新增加的正数子区间为最后一个零后面所有的正数区间数+1(正数乘以正数为正数,再加上本次输入的这个数本身),新增加的负数区间为最后一个零后面所有的负数子区间数,新增的零区间为之后一个零及其以前所有元素的数量。
3: 如果输入的数是一个负数,则新增加的正数区间是最后一个零后面所有的负数区间数(因为正数乘以负数会变成负数),新增加的负数区间等于最后一个零后面所有的正数区间数+1,新增的零区间为之后一个零及其以前所有元素的数量。(即输入一个负数时,以前的正数区间变为负数区间,负数区间变为正数区间)
4:避免溢出,我们用long long
代码:

#include <stdio.h>
long long n,m,a,op,ans1,ans2,ans3,t,r,temp1,temp2,temp3,q;
void nb(long long x,long long p)
{
    if(x==0)
    {
        ans2+=p;
        temp1=0;
        temp3=0;
        temp2=p;
    }
    else if(x>0)
    {
        ans1+=temp1+1;
        ans2+=temp2;
        ans3+=temp3;
        temp1++;
    }
    else
    {
        ans1+=temp3;
        ans2+=temp2;
        ans3+=temp1+1;
        q=temp1;
        temp1=temp3;
        temp3=q+1;
    }
}
int main()
{
    scanf("%lld%lld",&n,&m);
    for(long long i=1;i<=n;i++)
    {
        scanf("%lld",&a);
        nb(a,i);
    }
    r=n;
    while(m--)
    {
        scanf("%lld",&op);
        if(op==1)
        {
            scanf("%lld",&t);
            for(long long i=r+1;i<=r+t;i++)
            {
                scanf("%lld",&a);
                nb(a,i);
            }
            r+=t;
        }
        else if(op==2)
        {
            printf("%lld %lld %lld\n",ans1,ans2,ans3);
        }
    }
    return 0;
}
posted @ 2020-03-07 11:58  键盘_书生  阅读(59)  评论(0编辑  收藏  举报