The 2018 ACM-ICPC (青岛)-H题-Traveling on the Axis(找规律+前缀和)

版权声明:转载请告知博主并要注明出处嗷~ https://blog.csdn.net/Akatsuki__Itachi/article/details/82745169

好几个题的代码都找不到了,写一写打开cb唯一剩的一道题的代码吧。

题目链接

1代表绿灯,0代表红灯。

红灯的时候要等一秒,绿灯可以直接通过,穿过一个灯也需要耗费一秒钟。

问耗费的总时间。

具体计算方法见题目的hint......(

思路:

算是找了下规律,规律如下:

第一个灯如果为1,那么通过的时间为1秒,如果为0,那么时间需要两秒。

从第二个灯开始,如果当前灯的状态和前面的相同,那么时间加两秒,不同加一秒。

如第三组样例  11010

1+3+4+5+6

    1+2+3+4

        2+3+4

            1+2

                2

答案为43

那么再看上面的和,每次减去第一项(1或者2),后面的项有两种情况,可能会每一项减去2,也可能不变。

那么什么时候对应上面的两种情况呢?

再看

相邻的两种灯的状态有四种:00  01  10  11

只有当10的时候,后面的项不变,否则每项都减去了2.

最后只需要维护一个前缀和,每一次做个差分再加和即可。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<algorithm>
#define memset(a,v)  memset(a,v,sizeof(a))
#define max(a,b)   (a>b?a:b)
#define min(a,b)   (a<b?a:b)
#define swap(a,b)  (a=a+b,b=a-b,a=a-b)
#define eps 1.0E-8
using namespace std;
const int MAXL(1e5);
const int INF(0x7f7f7f7f);
const int mod(1e9+7);
typedef long long int LL;
char str[MAXL+50];
LL dp[MAXL+50];
LL a[MAXL+50];
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        memset(dp,0);
        LL ans=0;
        scanf("%s",str+1);
        int len=strlen(str+1);
        if(str[1]=='0')
            a[1]=2;
        else
            a[1]=1;
        for(int i=2;i<=len;i++)
        {
            if(str[i]==str[i-1])
                a[i]=a[i-1]+2;
            else
                a[i]=a[i-1]+1;
        }
        for(int i=1;i<=len;i++)
            dp[i]=dp[i-1]+a[i];
        ans=dp[len];
        LL temp=dp[len];
        for(int i=2;i<=len;i++)
        {
            if(str[i-1]=='0')
                temp-=2;
            else
                temp-=1;
            if(str[i]=='0'&&str[i-1]=='1')
                ans+=temp;
            else
                temp-=((len-i+1)*2),ans+=temp;
        }
        cout<<ans<<endl;

    }
}

猜你喜欢

转载自blog.csdn.net/Akatsuki__Itachi/article/details/82745169