FZU 1914 Funny Positive Sequence

题目链接:Funny Positive Sequence

题意:给出一个数列,如果它的前i(1<=i<=n)项和都是正的,那么这个数列是正的,问这个数列的这n种变换里,

A(0): a1,a2,…,an-1,an

A(1): a2,a3,…,an,a1

A(n-2): an-1,an,…,an-3,an-2

A(n-1): an,a1,…,an-2,an-1

有多少是正的数列。

思路:比赛的时候想了很久很久,肯定是要求在一次线性扫描里solve这个两重循环才能解决的问题,最后想到应该是计算负数会影响的项,然后大腿就想出来了。

很巧妙地线性扫描,每次只要向前遍历,看这个负数会影响到哪一项,继续向前找就可以了,有些负数可以跳过的,于是就是一次循环解决了,模拟一下过程就知道了。注意最后,要扫描到temp>0或者直接扫描到i=0就可以了。【ACMer的脑洞可怕....】

#include <stdio.h>
#include <string.h>
#include <iostream>
#define maxn 500010
using namespace std;

double a[maxn];
int cas = 0;

int main() {
    int t;
    scanf("%d", &t);
    while(t--) {
        int n;
        scanf("%d", &n);
        for (int i=0; i<n; ++i) {
            scanf("%lf", &a[i]);
        }

        double temp = 0;
        bool vis[maxn];
        memset(vis, 0, sizeof(vis));
        bool flag = true;
        int sum = n;

        for (int i=n-1; i>=0; --i) {
            if (a[i]<=0 && flag) flag = false;
            if (flag == false) {
                temp += a[i];
                if (temp <= 0) vis[i] = 1, sum--;
                else flag = true, temp = 0;
            }
        }

        if (temp <= 0) {
            for (int i=n-1; i>=0; --i) {
                temp += a[i];
                if (temp <= 0 && !vis[i]) {
                    vis[i] = 1;
                    sum--;
                }
                else if (temp > 0) break;
            }
        }

        printf("Case %d: %d
", ++cas, sum);
    }
    return 0;
}

  

原文地址:https://www.cnblogs.com/icode-girl/p/5409938.html