题目大意:
Bao在数轴的间隔[0,n]上散步,但他不能自由移动,[1,n]处有n个路灯, 1代表绿灯可以行走,0代表红灯不能行走,Bao在每一秒可以做两件事情,事情一:判断路灯的颜色,如果是红灯,不走,如果是绿灯,走;事情二:将当前所有的路灯的颜色改变(0变1,1变0), 求出走所有路径所用的时间
(只能从前往后走,可以从0开始走,但路灯从1处才开始有)
(在一秒内可以做出两件事情,判断灯色,如果为红灯,等着,这是1s内完成的。如果为绿灯,走,紧接着变颜色,这也是1s内完成的)
思路:
这就是一个思维题,找规律。
例: 1 1 0 1 0
从0:1 3 4 5 6
从1: 1 2 3 4 除第一个数其他都为上一行数减二
从2: 2 3 4 除第一个数其他都和上一行数一样
从3: 1 2 所有数其他都为上一行数减二
从4: 2 除第一个数其他都和上一行数一样
相邻数字的情况一共有4种:
情况一:1 1-------除第一个数其他都为上一行数减二
情况二:0 1-------所有数其他都为上一行数减二
情况三:0 0-------和情况二一样
情况四:1 0-------除第一个数其他都和上一行数一样
我们正是用这个规律来通过前面的结果推后面的结果的。
代码:
#include<algorithm>
#include<iostream>
#include<limits.h>
#include<cstdlib>
#include<cstring>
#include<cassert>
#include<string>
#include<cstdio>
#include<bitset>
#include<vector>
#include<cmath>
#include<ctime>
#include<stack>
#include<queue>
#include<deque>
#include<list>
#include<set>
#define MAXN 100001
#define mod 3
typedef long long ll;
using namespace std;
int n;
int len;
int main()
{
cin>>n;
while (n--)
{
ll sum=0;
ll ans=0;
ll kl=0;
char op[MAXN];
scanf("%s",op);
len=strlen(op);
bool zk=true;//zk判断红绿灯是否变化了,如果没变化,就是true,如果变化了,就是false
for(int i=0;i<len;i++)//这个循环是求的从0--1,0--2.....0--len所需要的时间的总和
{
//当当前所遇到的是红灯时,我们需要2秒钟才能通过,并且红绿灯不变,当遇到的是绿灯时,我们需要1秒钟才能通过,红绿灯变
if(op[i]=='0')
{
if(zk)
kl+=2;
else
kl+=1;
zk=true;
}
else
{
if(zk)
kl+=1;
else
kl+=2;
zk=false;
}
ans+=kl;//k1是从0位置到i位置所需要的时间
}
sum=ans;
int m=len;
for(int i=1;i<len;i++)//下面就是求剩下的所有区间的结果,我们利用上面求的结果来求。
{
if(op[i-1]=='1'&&op[i]=='1')
ans=ans-(2*(m-1)+1);
else if(op[i-1]=='1'&&op[i]=='0')
ans-=1;
else if((op[i-1]=='0'&&op[i]=='1')||(op[i-1]=='0'&&op[i]=='0'))
ans=ans-2*m;
m--;
sum+=ans;
}
cout<<sum<<endl;
}
}