Traveling on the Axis (The 2018 ACM-ICPC Asia Qingdao Regional Contest, Online)

题目链接:

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=4054

题意就是一个小孩走一段路,这条路上有n个红绿灯,并且告诉了你初始红绿灯的状态,用1表示路灯,0表示红灯,并且没经过一秒红绿灯就转换,从绿灯变为红灯或是从红灯变为绿灯。小孩走这一段路,如果碰到了绿灯直接走过去,如果碰到了红灯停一秒钟等红灯变为绿灯在走过去,定义t(p,q)为从p点走到q点所需要的时间,q>p,并且q和p可以取任何值,问t(p,q)的总和是多少。

直接画图找规律,可以发现,如果是红灯的话,sum=sum-2-2*(thenum-1);第一个是绿灯第二个是红灯的话,是sum=sum-1;第一个是绿灯,第二个是绿灯的话,是sum=sum-1-2*(thenum-1); 其中sum是从第i个点出发,走到i+1,i+2.。。。i+n的和。thenum是还剩下几个点。

详情见代码:

#include <iostream>
#include <cstring>
#include <stdio.h>
using namespace std;
const int inf=1e5+7;
int arr[2][inf];
typedef long long ll;

int main()
{
	int T;
	scanf("%d",&T);
	string str;
	while(T--)
	{
		cin>>str;
		for(int i=0;i<str.length();i++)		 
		{
			arr[0][i]=str[i]-48;
			arr[1][i]=1-arr[0][i];	//其中技巧使用。 
		}	
		int len=str.length();			
		ll sum1=0,sum=0;					//这里的sum是零。 
		int k=0;					  
		for(int i=0;i<len;i++)			  
		{
			if(arr[k][i]==0)		//即使是过去之后任然是不变的。	 
			{
				sum1=sum1+2; 			//只求算出一层的来。 
				sum+=sum1;
			} 
			else
			{
				sum1=sum1+1;
				sum+=sum1;
				k=(k+1)%2;				 
			} 
		}
		sum1=0;
		ll temp=0;
		ll ans=sum;				 
		int thenum=str.length();	
		k=0;
		for(int i=0;i<len-1;i++)		//到3,和4正好对应。 
		{
			if(arr[k][i]==0)
			{
				sum=sum-2-2*(thenum-1);
				thenum--;		  
				ans+=sum;	
			}
			else if(arr[k][i]==1&&arr[k][i+1]==0)		//说明是一。不论是哪一个都是要加一的。 
			{
				sum=sum-1;
				thenum--;
				ans+=sum;		
			} 
			else
			{
				sum=sum-1-2*(thenum-1);
				thenum--;
				ans+=sum;
			}
		}													
		cout<<ans<<endl;
	}
	return 0;	
} 

猜你喜欢

转载自blog.csdn.net/weixin_40799464/article/details/84289566