[experience summary] for the optimization of storage form, PTA 7-3 Icelanders

Keywords: Python Hash table

7-3 Icelanders (25 points)

Title Description

In the 2018 World Cup, Iceland became famous because of its 1-1 draw with the powerful Argentina. Good people find that Icelanders seem to have a "son" behind their names, so some netizens popularize science as follows:

Icelanders follow the old Viking patriarchal surname system. The child's surname is equal to the father's name plus the suffix. If it is a son, add sson and a daughter add sdottir. Because Iceland has a small population, in order to avoid the reproduction of close relatives, locals use an App to check whether their ancestors have been connected for several generations before communication. Please realize the function of this App.

Input format:

Input first gives a positive integer N on the first line ( 1 < N ≤ 1 0 5 ) (1<N≤10 ^5 ) (1 < N ≤ 105), is the local population. Then N lines, each line gives a person's first name in the format of first name and last name (with gender suffix), and both strings are composed of no more than 20 lowercase English letters. Viking descendants can judge their gender by the suffix of their surname, while others add m after their surname to indicate male and f to indicate female. The title guarantees that the origin of each Viking family given is male.

The next line gives the positive integer M, which is the number of queries. Then, in line M, each line gives a pair of names in the format of first name 1 last name 1 first name 2 last name 2. Note: the last name here does not have a suffix. All four strings consist of no more than 20 lowercase letters.

The title guarantees that there are no two people with the same name.

Output format:

For each query, the following information is displayed in one row according to the results:

If two people are opposite sex and there is no common ancestor within five generations, Yes is output;
If two people are heterosexual, but there are common ancestors within five generations (excluding the fifth generation), output No;
If two people are of the same sex, output Whatever;
If one person is not in the list, NA is output.
The so-called "no public ancestor within five generations" means that the two people's public ancestors (if they exist) must be higher than either party's great grandparents.

Input example:

15
chris smithm
adam smithm
bob adamsson
jack chrissson
bill chrissson
mike jacksson
steve billsson
tim mikesson
april mikesdottir
eric stevesson
tracy timsdottir
james ericsson
patrick jacksson
robin patricksson
will robinsson
6
tracy tim james eric
will robin tracy tim
april mike steve bill
bob adam eric steve
tracy tim tracy tim
x man april mikes

sample output

Yes
No
No
Whatever
Whatever
NA

Upper code

Wild code

n = int(input())
d = {}
for i in range(n):
	a,b = input().split()
	d[a] = b
def isMale(name):
	return d[name][-4:] == 'sson' or d[name][-1] == 'm'
def isNative(name):
	return not (d[name][-1] == 'm' or d[name][-1] == 'f')
def getName(lastName):
	if lastName[-4:] == 'sson':
		return lastName[:-4]
	return lastName[:-7]

def check():
	ask = list(input().split())
	#if ask[0] not in d.key or ask[2] not in d.key:
	if ask[0] not in d.keys() or ask[2] not in d.keys():
		print('NA')
		return
	if isMale(ask[0]) == isMale(ask[2]):
		print('Whatever')
		return
	#if not isNative(ask[0]) or not isNative(ask[2]):
	#	print('Yes')
	#	return
	name1 = ask[0]
	x = 1
	while True:
		y = 1
		name2 = ask[2]
		while True:
			if x >= 5 and y >= 5:break
			if name1 == name2:
				print('No')
				return
			if not isNative(name2):break
			name2 = getName(d[name2])
			y += 1
		if not isNative(name1):break
		name1 = getName(d[name1])
		x += 1
	print('Yes')

q = int(input())
for _ in range(q):
	check()

Better code

This code is referenced from Leng Yun's blog

D = {}

class Person:
	def __init__(self,lastName):
		self.sex = 'm'
		self.fa = ''
		if lastName[-1] == 'f' or lastName[-1] == 'r':
			self.sex = 'f'
		if lastName[-1] == 'r':
			self.fa = lastName[:-7]
		elif lastName[-1] == 'n':
			self.fa = lastName[:-4]
		#print(self.sex,self.fa)

def solve():
	a,b,c,d = input().split()
	if a not in D.keys() or c not in D.keys():
		print('NA')
		return
	elif D[a].sex == D[c].sex:
		print('Whatever')
		return
	
	i = a
	x = 0
	while i:
		x += 1
		j,y = c,0
		while j:
			y += 1
			if y >= 5 and x >= 5:break
			if i == j:
				print('No')
				return
			j = D[j].fa
		i = D[i].fa
	print('Yes')
def main():
	s = ''
	for _ in range(int(input())):
		a,b = input().split()
		D[a] = Person(b)
	for _ in range(int(input())):
		solve()

if __name__ == '__main__':
	main()

The idea of this problem is very simple, that is, using a hash table.

This topic is issued to emphasize the importance of data storage form for code implementation.
It can be seen that when storing everyone's data, the second code uses the Person class to analyze and store the Person's gender and parent name. Compared with the first code, which is directly stored in string form, the implementation of the second code is much simpler when doing operation analysis later.

Data can be stored in various forms. We should choose the form that is most conducive to subsequent operation and analysis for storage.

Original is not easy, thank you for your support.

Posted by nickcwj on Sun, 31 Oct 2021 01:47:53 -0700