我们有N条电线,每个电线两端是不同规格的接口(a/b/c/d....),同一根电线两端的接口规格可能是不同的,只有相同规格的接口才能把两根电线连接在一起,设计一个程序,判断所有这些电线是否能合并为一根长电线。
输入:N行,每行是两个字符串,表示电线的规格,如
a a
a b
b c
输出:是否能拼接为一根电线
解题思路:采用数学思想,找规律。
已知N根线,则共有2N个端点,即2N个字符。
假设把N根线连接起来,则如图所示,大方框内共有2N-2个端点,另外两端各有一个端点。则对于中间M来说,对于任何字符出现的次数一定是偶数,那么可以分成以下几种情况来考虑:
1、A和B字符不同,且已经出现在了M中
2、A和B字符不同,A出现在了M中,B未出现在M中
3、A和B字符不同,A和B都没有出现在M中
2019-07-25:补充:缺少一种情况,A和B字符不同,A没有出现在M中,而B出现在M中。
4、A和B字符相同,A和B出现在M中
5、A和B字符相同,A和B未出现在M中
6、A和B字符相同,且和M字符相同,即2N个端点只出现一个字符。
则基于以上情况我们可以有以下分析:
- 对于该情况,必定有两个字符(A、B,且均大于2的奇数)出现次数为奇数,其他字符为偶数
- 对于该情况,必定有两个字符(A、B,且A大于2的奇数,B=1,或A=1,B大于2)出现次数为奇数,其他字符为偶数
- 对于该情况,必定有两个字符(A、B,且AB均出现1次),出现次数为奇数,其他字符为偶数
- 对于该情况,所有字符出现次数均为偶数,且A(或B)出现次数大于等于4次
- 对于该情况,所有字符出现次数均为偶数,且A(或B)出现次数等于2次
也就是对于这两种情况,所有字符出现的次数均为偶数。但是,对于4、5,有特殊情况会不符合要求,也就是对于每根或部分线,两个端点的字符相同。如图所示:
6、只出现一种字符
所以综合以上情况我们可以得出可以连接成一条线的结论:
- 所有字符必定有两个字符出现次数为奇数,其他所有字符为偶数(字符种数大于等于2)
- 所有字符出现次数都为偶数,且每根线两端都不能为相同的字符(字符种数大于等于2)
- 只有一种字符
代码:
def check_ok(data):
_array = {}
for msg in data:
for m in msg:
if m not in _array.keys():
_array[m] = 1
else:
_array[m] += 1
print "_array:{0}".format(_array)
if len(_array.keys()) == 1:
return True
elif len(_array.keys()) >= 2:
jishu = 0
oushu = 0
for k,v in _array.items():
if v%2 == 0:
oushu += 1
else:
jishu += 1
if jishu == 2:
return True
elif jishu == 0:
for msg in data:
if msg[0] == msg[1]:
return False
return True
return False
def make_line():
num = raw_input()
if num:
num = int(num)
i = 0
data = []
while(i < num):
temp = raw_input().split(' ')
data.append(temp)
i += 1
print check_ok(data)
测试用例:
---------------test1--------------
3
a b
b a
c c
_array:{'a': 2, 'c': 2, 'b': 2}
False
---------------test2--------------
3
a a
b b
c c
_array:{'c': 2, 'b': 2, 'a': 2}
False
---------------test3--------------
3
a c
c d
d f
_array:{'c': 2, 'd': 2, 'f': 1, 'a': 1}
True
---------------test4--------------
4
c d
m f
x y
z z
_array:{'f': 1, 'x': 1, 'z': 2, 'm': 1, 'y': 1, 'c': 1, 'd': 1}
False
---------------test5--------------
3
a a
a a
a a
_array:{'a': 6}
True