2018 icpc青岛赛区网络赛 H题

题目大意:

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;
    }
}


​

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值