好几个题的代码都找不到了,写一写打开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;
}
}