字符串压缩

编程之美比赛的一道题,一直是RE,不知道为什么。可能是我对G++不熟悉吧,代码贴出来,如果谁发现问题,告诉我一下!
时间限制:8000ms
单点时限:4000ms
内存限制:256MB

描述

你的硬盘上有一个神秘的文件占用了大量空间,你决定将其压缩以节省空间。不幸的是,你还没有安装任何压缩软件,所以你决定自己编写一个压缩程序。你发现这是一个文本文件,包括很多行。每行是一个长度恰好为L的字符串,而且字符串可能有重复。行的顺序并不重要,换言之,打乱顺序之后仍然可以认为文件内容和原来相同。

例如,这个文件的内容可以是这样的:

bar

car

bat

cat

cat


经过一段时间观察,你发现同一列的字符往往是相同的,于是你设计了一个简单的压缩框架。首先以某种策略调整行的顺序,然后把所有字符串按照先列后行的顺序变换成单个字符串,例如上面的例子,不调整顺序则直接变换成:

bcbccaaaaarrttt

然后使用游程编码(RLE)的到压缩变换后的字符串:

1b1c1b2c5a2r3t

当然也可以先调换顺序:

car

cat

cat

bat

bar

这样的压缩字符串为:

3c2b5a1r3t1r

比不调整顺序的稍短一些。

现在,你已经得到了两个不同的压缩字符串,你想知道他们解压后的文件是否相同,请写一个程序解决这个问题。


输入

第一行是一个整数T (T <= 30),表示测试数据组数。

每组测试数据占三行。第一行为整数L,表示原始文件中每一行字符串的长度。第二行和第三行分别是两个压缩字符串,格式如c1 n1 c2 n2 … cMnM,表示字符ci连续出现了ni次。具体格式见样例。输入字符串只含a到z的小写字母,确保压缩字符串合法有效,且不为空。


输出

对每组测试数据,首先输出”Case x: ”,其中x表示测试数据编号。如果两个压缩字符串对应于相同的文件内容,则输出”Yes”,否则输出”No”。


数据范围

小数据:1<=L<=10, 1<=ni<=100,压缩字符串长度不超过10^4

大数据:1<=L<=1000, 1<=ni<=10^9,压缩字符串长度不超过10^6



样例输入
2
3
1b1c1b2c5a2r3t
3c2b5a1r3t1r
2
20a20b10a20b10a
20a20b20a20b
样例输出
Case 1: Yes
Case 2: No
#include<iostream>
#include<string>
using namespace std;
string GetStr(string str)
{
	string result1;
	unsigned long long l;
	for (unsigned long long k=0;k<str.length();k=k+2)
	{
		l=str.at(k)-'0';
		if (str.at(k+1)>='0'&&str.at(k+1)<='9')
		{
			k++;
			l=l*10+str.at(k)-'0';
		}
		for ( unsigned long long i=0;i<l;i++)
		{
			result1=result1+str.at(k+1);
			
		}
	}
	return result1;
}
string GetOrgial(string str,unsigned long long L)
{
	unsigned long long k=str.length()/L;
	string result1;
	for (unsigned long long i=0;i<k;i++)
	{
		for (unsigned long long j=i;j<str.length();j=j+k)
		{
			result1=result1+str.at(j);
		}
	}
	return result1;
}
int main()
{
	int T;
	unsigned long long L;
	string C1,C2;
	cin>>T;
	
	for (int k=1;k<=T;k++)
	{
		cin>>L;
		cin>>C1;
		cin>>C2;
		bool test=true;
		string C=GetStr(C1);
		string CSub=GetStr(C2);
		if (C.length()!=CSub.length())
		{
			cout<<"Case "<<k<<": No"<<endl;
			continue;
		}
		string Orginal1=GetOrgial(C,L);
		unsigned long long m=C.length()/L;
		for (unsigned long long i=0;i<m;i++)
		{
			string sub;
			for (unsigned long long j=i;j<CSub.length();j=j+m)
			{
				sub=sub+CSub.at(j);
			}
			unsigned long long n=Orginal1.find(sub,0);
			if (n%L!=0)
			{
				cout<<"Case "<<k<<": No"<<endl;
				test=false;
				break;
				
			}
		}
		if(test)
		cout<<"Case "<<k<<": Yes"<<endl;

	}
	return 1;
}


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值