南邮 OJ 2071 大发明家的童年

大发明家的童年

时间限制(普通/Java) :  1000 MS/ 3000 MS          运行内存限制 : 65536 KByte
总提交 : 84            测试通过 : 16 

比赛描述

        多少年后,当大发明家黑默丁格超神的那一刻,准会想起父亲着带他学习《通信原理》的那个下午;

        数字信号是由01构成的数字串,传输数字信号的时候会先经过转码处理然后进行传输,下面给出两种码的说明:

        AMI码:信号码中信号0不变,信号1交替变成+1,-1,(这里我们规定第一个1变为-1)

        1 0 0 0 0 1 0 0 0 0 1 1 0 0 0 0 1 1 改写成AMI码之后就成为了:

        -1 0 0 0 0 +1 0 0 0 0 -1 +1 0 0 0 0 -1 +1

        HDB3码:检查信息码中连"0"的个数,若连"0"个数小于3,则HDB3码与AMI码完全相同

        当出现4个以上连"0"的时候,每4个连"0"变为000V,V的极性与前一个非0码极性相同,

        相邻V之间的极性必须相反,所以如果相邻V之间1码的个数为偶数,则后一段000V变为B00V,B的极性与前一个非0码相反,V的极性要与该B相同,同时后面的非0码的极性也要从V码开始再交替变化,即后面的1要根据最后的V的极性进行交替

        现在给定一串信息原码,求修改之后的HDB3码。

    (顺带一提,出题人绝对不是抱着被通原虐了然后想要虐大家这样邪恶想法才出这道题的,绝对..(^.^)



输入

单组样例,先输入一个正整数n,表示信息原码的长度,4n100;

接着,输入n个整数,表示由0,1组成的数字表示信息原码的构成。

题目保证第一段4连“0”之前肯定会有1。

输出

输出一行:根据条件分别输出0,-1,+1,+B,-B,+V,-V,互相之间用空格隔开,最后一个码后面不要空格。

样例输入

18
1 0 0 0 0 1 0 0 0 0 1 1 0 0 0 0 1 1

样例输出

-1 0 0 0 -V +1 0 0 0 +V -1 +1 -B 0 0 -V +1 -1

题目来源

kojimai




#include<iostream>
#include<string>
using namespace std;

int main()
{
	int length,i;
	bool previousOneIsPositive = 1;
	bool previousVIsPositive = 1;
	bool IsFirstV = 1;
	int continueZeroCount = 0;
	string *s;
	cin>>length;
	s = new string[length];
	for(i=0;i<length;++i)
	{
		cin>>s[i];
	}
	for(i=0;i<length;++i)//转换成AMI码:信号码中信号0不变,信号1交替变成+1,-1,(这里我们规定第一个1变为-1)
	{
		if("1"==s[i])
		{
			if(previousOneIsPositive)
			{
				s[i] = "-1";
				previousOneIsPositive = 0;
			}
			else
			{
				s[i] = "+1";
				previousOneIsPositive = 1;
			}
		}
	}
	for(i=0;i<length;++i)//当出现4个以上连"0"的时候,每4个连"0"变为000V,V的极性与前一个非0码极性相同
	{
		if("0"==s[i])
		{
			++continueZeroCount;
			if(continueZeroCount>=4)
			{
				continueZeroCount = 0;
				if(previousOneIsPositive)
				{
					s[i] = "+V";
				}
				else
				{
					s[i] = "-V";
				}
			}
		}
		else
		{
			continueZeroCount = 0;
			if("+1"==s[i])
			{
				previousOneIsPositive = 1;
			}
			else
			{
				previousOneIsPositive = 0;
			}
		}
	}
	/*
	如果相邻V之间1码的个数为偶数,则后一段000V变为B00V,B的极性与前一个非0码相反,
	V的极性要与该B相同,同时后面的非0码的极性也要从V码开始再交替变化,
	即后面的1要根据最后的V的极性进行交替
	*/
	for(i=0;i<length;++i)
	{
		if("+1"==s[i])
		{
			previousOneIsPositive = 1;
		}
		else if("-1"==s[i])
		{
			previousOneIsPositive = 0;
		}
		else if("-V"==s[i])
		{
			if(!previousVIsPositive && !IsFirstV)	//相邻V之间的极性必须相反
			{
				s[i-3] = "+B";
				s[i] = "+V";
				previousVIsPositive = 1;
				for(int j=i+1;j<length;++j)
				{
					if("+V"==s[j])
					{
						s[j] = "-V";
					}
					else if("-V"==s[j])
					{
						s[j] = "+V";
					}
					else if("-1"==s[j])
					{
						s[j] = "+1";
					}
					else if("+1"==s[j])
					{
						s[j] = "-1";
					}
				}
			}
			else
			{
				previousVIsPositive = 0;
			}			
			IsFirstV = 0;
		}
		else if("+V"==s[i])
		{
			if(previousVIsPositive && !IsFirstV)	//相邻V之间的极性必须相反
			{
				s[i-3] = "-B";
				s[i] = "-V";
				previousVIsPositive = 0;
				for(int j=i+1;j<length;++j)
				{
					if("+V"==s[j])
					{
						s[j] = "-V";
					}
					else if("-V"==s[j])
					{
						s[j] = "+V";
					}
					else if("-1"==s[j])
					{
						s[j] = "+1";
					}
					else if("+1"==s[j])
					{
						s[j] = "-1";
					}
				}
			}
			else
			{
				previousVIsPositive = 1;
			}
			IsFirstV = 0;
		}
	}

	cout<<s[0];
	for(i=1;i<length;++i)
	{
		cout<<" "<<s[i];
	}
	cout<<endl;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值