The 2018 ACM-ICPC Asia Qingdao Regional Contest, Online _H_Traveling on the Axis(前缀+细节)

Traveling on the Axis


Time Limit: 1 Second      Memory Limit: 65536 KB


题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5809

BaoBao is taking a walk in the interval  on the number axis, but he is not free to move, as at every point  for all , where  is an integer, stands a traffic light of type  ().

BaoBao decides to begin his walk from point  and end his walk at point  (both  and  are integers, and ). During each unit of time, the following events will happen in order:

  1. Let's say BaoBao is currently at point , he will then check the traffic light at point . If the traffic light is green, BaoBao will move to point ; If the traffic light is red, BaoBao will remain at point .

  2. All the traffic lights change their colors. If a traffic light is currently red, it will change to green; If a traffic light is currently green, it will change to red.

A traffic light of type 0 is initially red, and a traffic light of type 1 is initially green.

Denote  as the total units of time BaoBao needs to move from point  to point . For some reason, BaoBao wants you to help him calculate

                                                              

where both  and  are integers. Can you help him?

Input

There are multiple test cases. The first line of the input contains an integer , indicating the number of test cases. For each test case:

The first and only line contains a string  (, ,  for all ), indicating the types of the traffic lights. If , the traffic light at point  is of type 0 and is initially red; If , the traffic light at point  is of type 1 and is initially green.

It's guaranteed that the sum of  of all test cases will not exceed .

Output

For each test case output one line containing one integer, indicating the answer.

Sample Input

3
101
011
11010

Sample Output

12
15
43

Hint

For the first sample test case, it's easy to calculate that , , , ,  and , so the answer is .

For the second sample test case, it's easy to calculate that , , , ,  and , so the answer is .

题意:给出01字符串序列,1代表绿灯,0代表红灯,每一秒发生两种事件:

1、若为绿灯则当前可以通行;

2、全部灯的变成相反的颜色。

解题思路:

  前缀的思想,过每个路灯都只有两种情况,花费为1,花费为2。那么,我们可以记录所有的单位距离通过时间。

第一段时间对答案的贡献为:通过时间*(每次总的次数)*(重复次数) ,特判从当前i出发,i为‘0’则需要增加次数,i为‘1’则需要减少

次数。

#include<bits/stdc++.h>
#define rep(i,j,k) for(int i=j;i<k;i++)
#define per(i,j,k) for(int i=j;i<=k;i++)
#define IO ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
using namespace std;
typedef long long ll;
const int maxn = (int)1e5+5;
int sum[maxn];
int a[maxn];
int b[maxn];
int main(void)
{
    IO
    int T;cin>>T;
    while(T--)
    {
        string s;
        cin>>s;
        int tot=0;
        int len =s.length();
        a[0] = 1;
        b[0] = 1;
        rep(i,0,len)
        {
            a[i+1]=s[i]-'0';
            b[i+1]=a[i+1];
        }
        int flag=0;
        int t=0;
        rep(i,1,len+1)
        {
            t=0;
            if(flag&1) a[i]^=1;
            t++;
            flag++;
            if(!a[i]) {
                t++;
                flag++;
            }
            sum[i] = t;
            //tot +=sum[i];
        }
        sum[0] = 0;
       // rep(i,0,len+1) cout<<sum[i]<<endl;
       // cout<<endl;
        ll ans = 0;
        rep(i,1,len+1)
        {
            ans += (ll)(sum[i])*(len-i+1)*i;
            //存在一次以i为起点的遍历(共len-i+1次)
            if(!a[i])
                ans -= (len-i+1); //如果遍历后序列通行过去为0则需要还原成1,(sum[i]-1)(len-i+1)*1

            if(!b[i])
                ans += (len-i+1);//如果原序列为0则需要还原成1,(sum[i]+1)(len-i+1)*1

        }
        cout<<ans<<endl;
    }
}

%大神的代码:

#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
int main(void)
{
	int T;cin>>T;
	while(T--)
	{
		string s;
		cin>>s;
		int n=s.length();
		ll ans = 0;
		for(int i=0;i<n;i++) ans += 1LL*(n-i)*(i+1); 
		for(int i=0;i<n;i++)
		{
			if(i&&s[i]==s[i-1]) ans += 1LL*(n-i)*i;     
			if(s[i]=='0') ans += (n-i);
		}
		cout<<ans<<endl; 
	}
}

猜你喜欢

转载自blog.csdn.net/Achanss/article/details/82748684