主题:第42次编程比赛第一题
argentmoon [专家分:13260] 发布于 2006-09-22 12:39:00
[center]二进制编码问题[/center]
给定两个二进制编码(0,1序列),请问从一个编码转换成另一个编码所需的最少次数是多少?
编码转换规则:每一次都可以将编码中任意长度的一段倒置(是连续的一段)。 (1010 倒置后为 0101, 111000倒置后为000111)
请编程找出[b]最少[/b]所需要的转换次数。
输入第一行是第一个二进制编码,第二行是第二个进制编码,输出最少的次数(输入输出采用标准输入输出流)
注: 数据保证两个编码肯定可以相互转换。而且编码最长为20个字符。
注:倒置不是0,1互换,而是英文单词reverse的意思
hint:请注意效率问题。
输入事例:
1001
0110
输出事例:
2
输入事例2:
011000
000110
输出事例2:
1
回复列表 (共22个回复)
21 楼
rickone [专家分:15390] 发布于 2006-09-25 00:08:00
唉,今天本想改进一下,发现好多错误(有的还不知道原因现在-_-!)
还以为昨天写的正确性没问题了,今天只想改进下提高效率,发现了一些CASE,大家也来验证一下吧:
1,
010110000011101
001101010101010
4
2,
0001110101
1101010100
2
3,
10100010000000011001
00001010010001010001
3
这几个我用笔算过了,至多是下面那个数字。
另外搞些测速度的CASE:
昨天LZ给了我一个超猛的CASE
01010101010101010101
00000000001111111111
我的所有今天的思路都来源于这个CASE~~~
我做的假设是‘这样的情况是最糟糕的’,所以测速就用一个n,表示有多少个1,然后像那样排开,比如:
n=7
01010101010101
00000001111111
6
n=8
0101010101010101
0000000011111111
7
一直想不到好的h函数,今天想到一个,回来一试,还不如双向广搜快,于是就出了今天写的四不像,双向A*- -,非常需要验证,现在已经头晕了,如果还给我一天时间,可能完善一下,只能说目前没有发现错误CASE,速度也还不错n=8时,P3机子上10s左右完成,我的机子太水了,你的机子好帮我试试n=10的超级变成CASE可不可以出结果;)
给大家这些数据,仅供参考。
22 楼
liren0 [专家分:260] 发布于 2006-09-25 09:43:00
#include <iostream.h>
#include <string.h>
int get_reverse_count(char * str1, char *str2, int len);
int main()
{
int n = 0;
char str1[20];
char str2[20];
unsigned int len;
cout << "请输入字符串1:";
cin >> str1;
cout << "请输入字符串2:";
cin >> str2;
if ((len =strlen(str1)) != strlen(str2))
return -1;
n = get_reverse_count(str1, str2, len);
cout << "The reverse count are:" << n<<endl;
return 0;
}
int get_reverse_count(char * str1, char *str2, int len)
{
int n, beg, i, j, k, end, count;
char *ptem = new char [len];
n = 0, count = 0;
while (n < len)
{
*(ptem + n) = *(str1 + n) - *(str2 + n);
++n;
}
beg = 0, end = len - 1;
while (*(ptem + end) == 0)
--end;
while (beg < end)
{
while (*(ptem + beg) == 0)
++beg;
i = beg, j = k = end;
while (i <= j)
{
if (*(ptem + i) + *(ptem + j) == 0)
{
++i;
--j;
}
else
{
i = beg;
j = --k;
}
}
if (k > beg)
++count;
else
return -1;
beg = k + 1;
}
return count;
}
我来回复