diff --git a/A Chocolate Fiesta.py b/A Chocolate Fiesta.py index 35a5e7e..7505d17 100644 --- a/A Chocolate Fiesta.py +++ b/A Chocolate Fiesta.py @@ -1,75 +1,75 @@ -# -*- coding: utf-8 -*- -""" -Problem Statement - -Welcome to the exciting class of Professor Manasa. In each lecture she used to play some game while teaching a new -concept. Today's topic is Set Theory. For today's game, she had given a set A = {a1, a2, ...aN} of N integers to her -students and asked them to play the game as follows. - -At each step of the game she calls a random student and asks him/her to select a non-empty subset from set A such that -this subset had not been selected earlier and the sum of subset should be even. This game ends when all possible subsets -had been selected. Manasa needs your help in counting the total number of times students can be called assuming each -student gives the right answer. While it is given that if two numbers are same in the given set, they have different -colors. It means that if a1 = a2, then choosing a1 and choosing a2 will be considered as different sets. -""" -__author__ = 'Danyang' -MOD = 10**9+7 - - -class Solution(object): - def solve_error(self, cipher): - """ - count odd number and even number - :param cipher: the cipher - """ - N, lst = cipher - odd_cnt = len(filter(lambda x: x%2==1, lst)) - even_cnt = N-odd_cnt - - a = (2**even_cnt)%MOD - - result = 0 - result += a-1 - - i = 2 - comb = (odd_cnt)*(odd_cnt-1)/(1*2) - while i<=odd_cnt: - result += comb*a - result %= MOD - i += 2 - comb *= (odd_cnt-i+1)*(odd_cnt-i)/((i-1)*i) - comb %= MOD - - return result - - def solve(self, cipher): - """ - count odd number and even number - :param cipher: the cipher - """ - N, lst = cipher - odd_cnt = len(filter(lambda x: x%2==1, lst)) - even_cnt = N-odd_cnt - - a = (2**even_cnt)%MOD - b = (2**(odd_cnt-1))%MOD - - if odd_cnt!=0: - result = a-1+(b-1)*a - else: - result = a-1 - - return result%MOD - - -if __name__=="__main__": - import sys - - f = open("1.in", "r") - # f = sys.stdin - N = int(f.readline().strip()) - lst = map(int, f.readline().strip().split(' ')) - cipher = N, lst - # solve - s = "%s\n"%(Solution().solve(cipher)) - print s, \ No newline at end of file +# -*- coding: utf-8 -*- +""" +Problem Statement + +Welcome to the exciting class of Professor Manasa. In each lecture she used to play some game while teaching a new +concept. Today's topic is Set Theory. For today's game, she had given a set A = {a1, a2, ...aN} of N integers to her +students and asked them to play the game as follows. + +At each step of the game she calls a random student and asks him/her to select a non-empty subset from set A such that +this subset had not been selected earlier and the sum of subset should be even. This game ends when all possible subsets +had been selected. Manasa needs your help in counting the total number of times students can be called assuming each +student gives the right answer. While it is given that if two numbers are same in the given set, they have different +colors. It means that if a1 = a2, then choosing a1 and choosing a2 will be considered as different sets. +""" +__author__ = 'Danyang' +MOD = 10 ** 9 + 7 + + +class Solution(object): + def solve_error(self, cipher): + """ + count odd number and even number + :param cipher: the cipher + """ + N, lst = cipher + odd_cnt = len(filter(lambda x: x % 2 == 1, lst)) + even_cnt = N - odd_cnt + + a = (2 ** even_cnt) % MOD + + result = 0 + result += a - 1 + + i = 2 + comb = (odd_cnt) * (odd_cnt - 1) / (1 * 2) + while i <= odd_cnt: + result += comb * a + result %= MOD + i += 2 + comb *= (odd_cnt - i + 1) * (odd_cnt - i) / ((i - 1) * i) + comb %= MOD + + return result + + def solve(self, cipher): + """ + count odd number and even number + :param cipher: the cipher + """ + N, lst = cipher + odd_cnt = len(filter(lambda x: x % 2 == 1, lst)) + even_cnt = N - odd_cnt + + a = (2 ** even_cnt) % MOD + b = (2 ** (odd_cnt - 1)) % MOD + + if odd_cnt != 0: + result = a - 1 + (b - 1) * a + else: + result = a - 1 + + return result % MOD + + +if __name__ == "__main__": + import sys + + f = open("1.in", "r") + # f = sys.stdin + N = int(f.readline().strip()) + lst = map(int, f.readline().strip().split(' ')) + cipher = N, lst + # solve + s = "%s\n" % (Solution().solve(cipher)) + print s, diff --git a/A journey to the Moon.py b/A journey to the Moon.py index a36c030..74adef1 100644 --- a/A journey to the Moon.py +++ b/A journey to the Moon.py @@ -1,80 +1,80 @@ -""" -Problem Statement - -The member states of the UN are planning to send 2 people to the Moon. But there is a problem. In line with their -principles of global unity, they want to pair astronauts of 2 different countries. - -There are N trained astronauts numbered from 0 to N-1. But those in charge of the mission did not receive information -about the citizenship of each astronaut. The only information they have is that some particular pairs of astronauts -belong to the same country. -""" -__author__ = 'Danyang' - - -class DisjointSet(object): - def __init__(self, n): - self.rank = [1 for _ in xrange(n)] - self.parent = [i for i in xrange(n)] - self.n = n - - def find(self, i): - if i==self.parent[i]: - return i - else: - self.parent[i] = self.find(self.parent[i]) # directly point to ancestor - return self.parent[i] - - def union(self, i, j): - x = self.find(i) - y = self.find(j) - - if x==y: return - self.parent[x] = y - self.rank[y] += self.rank[x] - - def card(self): - card = 0 - for i in xrange(self.n): - if self.parent[i]==i: - card += 1 - return card - - -class Solution(object): - def solve(self, cipher): - """ - Disjoint-set data structure - - Union-Find Algorithm - :param cipher: the cipher - """ - N, pairs = cipher - djs = DisjointSet(N) - for a, b in pairs: - djs.union(a, b) - - result = 0 - for i in xrange(N): - if djs.find(i)==i: # set representative - # result += (djs.rank[i])*(N-djs.rank[i])/2 # otherwise rounding error - result += (djs.rank[i])*(N-djs.rank[i]) - return result/2 - - -if __name__=="__main__": - import sys - - f = open("1.in", "r") - # f = sys.stdin - solution = Solution() - - N, I = map(int, f.readline().strip().split(' ')) - - pairs = [] - for i in xrange(I): - pairs.append(map(int, f.readline().strip().split(' '))) - - cipher = N, pairs - # solve - s = "%s\n"%(solution.solve(cipher)) - print s, \ No newline at end of file +""" +Problem Statement + +The member states of the UN are planning to send 2 people to the Moon. But there is a problem. In line with their +principles of global unity, they want to pair astronauts of 2 different countries. + +There are N trained astronauts numbered from 0 to N-1. But those in charge of the mission did not receive information +about the citizenship of each astronaut. The only information they have is that some particular pairs of astronauts +belong to the same country. +""" +__author__ = 'Danyang' + + +class DisjointSet(object): + def __init__(self, n): + self.rank = [1 for _ in xrange(n)] + self.parent = [i for i in xrange(n)] + self.n = n + + def find(self, i): + if i == self.parent[i]: + return i + else: + self.parent[i] = self.find(self.parent[i]) # directly point to ancestor + return self.parent[i] + + def union(self, i, j): + x = self.find(i) + y = self.find(j) + + if x == y: return + self.parent[x] = y + self.rank[y] += self.rank[x] + + def card(self): + card = 0 + for i in xrange(self.n): + if self.parent[i] == i: + card += 1 + return card + + +class Solution(object): + def solve(self, cipher): + """ + Disjoint-set data structure + + Union-Find Algorithm + :param cipher: the cipher + """ + N, pairs = cipher + djs = DisjointSet(N) + for a, b in pairs: + djs.union(a, b) + + result = 0 + for i in xrange(N): + if djs.find(i) == i: # set representative + # result += (djs.rank[i])*(N-djs.rank[i])/2 # otherwise rounding error + result += (djs.rank[i]) * (N - djs.rank[i]) + return result / 2 + + +if __name__ == "__main__": + import sys + + f = open("1.in", "r") + # f = sys.stdin + solution = Solution() + + N, I = map(int, f.readline().strip().split(' ')) + + pairs = [] + for i in xrange(I): + pairs.append(map(int, f.readline().strip().split(' '))) + + cipher = N, pairs + # solve + s = "%s\n" % (solution.solve(cipher)) + print s, diff --git a/ACM ICPC Team.py b/ACM ICPC Team.py index 7dd4b20..bb8e34e 100644 --- a/ACM ICPC Team.py +++ b/ACM ICPC Team.py @@ -1,60 +1,60 @@ -""" -You are given a list of N people who are attending ACM-ICPC World Finals. Each of them are either well versed in a topic -or they are not. Find out the maximum number of topics a 2-person team can know. And also find out how many teams can -know that maximum number of topics. - -Input Format - -The first line contains two integers N and M separated by a single space, where N represents the number of people, and M - represents the number of topics. N lines follow. -Each line contains a binary string of length M. In this string, 1 indicates that the ith person knows a particular -topic, and 0 indicates that the ith person does not know the topic. Here, 1 <= i <= 2, and it denotes one of the persons -in the team -""" -__author__ = 'Danyang' - - -class Solution(object): - def solve(self, cipher): - """ - bit manipulation - brute force O(N^2*M) - :param cipher: the cipher - """ - N, M, ppl = cipher - team_cnt = 0 - max_topic = 0 - for i in xrange(N): - for j in xrange(i+1, N): - cnt = self.common_topics(M, ppl[i], ppl[j]) - if cnt==max_topic: - team_cnt += 1 - elif cnt>max_topic: - team_cnt = 1 - max_topic = cnt - return "%d\n%d"%(max_topic, team_cnt) - - def common_topics(self, M, a, b): - topic = a|b - topic_cnt = bin(topic).count("1") # otherwise TLE - # topic_cnt = 0 - # for i in xrange(M): - # if topic&0x1==0x1: - # topic_cnt += 1 - # topic >>= 1 - return topic_cnt - - -if __name__=="__main__": - import sys - - f = open("1.in", "r") - # f = sys.stdin - N, M = map(lambda x: int(x), f.readline().strip().split(" ")) - ppl = [] - for i in xrange(N): - ppl.append(int(f.readline().strip(), 2)) - - cipher = [N, M, ppl] - s = "%s\n"%(Solution().solve(cipher)) - print s, +""" +You are given a list of N people who are attending ACM-ICPC World Finals. Each of them are either well versed in a topic +or they are not. Find out the maximum number of topics a 2-person team can know. And also find out how many teams can +know that maximum number of topics. + +Input Format + +The first line contains two integers N and M separated by a single space, where N represents the number of people, and M + represents the number of topics. N lines follow. +Each line contains a binary string of length M. In this string, 1 indicates that the ith person knows a particular +topic, and 0 indicates that the ith person does not know the topic. Here, 1 <= i <= 2, and it denotes one of the persons +in the team +""" +__author__ = 'Danyang' + + +class Solution(object): + def solve(self, cipher): + """ + bit manipulation + brute force O(N^2*M) + :param cipher: the cipher + """ + N, M, ppl = cipher + team_cnt = 0 + max_topic = 0 + for i in xrange(N): + for j in xrange(i + 1, N): + cnt = self.common_topics(M, ppl[i], ppl[j]) + if cnt == max_topic: + team_cnt += 1 + elif cnt > max_topic: + team_cnt = 1 + max_topic = cnt + return "%d\n%d" % (max_topic, team_cnt) + + def common_topics(self, M, a, b): + topic = a | b + topic_cnt = bin(topic).count("1") # otherwise TLE + # topic_cnt = 0 + # for i in xrange(M): + # if topic&0x1==0x1: + # topic_cnt += 1 + # topic >>= 1 + return topic_cnt + + +if __name__ == "__main__": + import sys + + f = open("1.in", "r") + # f = sys.stdin + N, M = map(lambda x: int(x), f.readline().strip().split(" ")) + ppl = [] + for i in xrange(N): + ppl.append(int(f.readline().strip(), 2)) + + cipher = [N, M, ppl] + s = "%s\n" % (Solution().solve(cipher)) + print s, diff --git a/Algorithmic Crush.py b/Algorithmic Crush.py index 68e7229..89d24ef 100644 --- a/Algorithmic Crush.py +++ b/Algorithmic Crush.py @@ -1,61 +1,61 @@ -""" -You are given a list of size N, initialized with zeroes. You have to perform M queries on the list and output the -maximum of final values of all the N elements in the list. For every query, you are given three integers a, b and k and -you have to add value k to all the elements ranging from index a to b(both inclusive). - -Input Format -First line will contain two integers N and M separated by a single space. -Next M lines will contain three integers a, b and k separated by a single space. -Numbers in list are numbered from 1 to N. - -Output Format -A single line containing maximum value in the final list. -""" -__author__ = 'Danyang' - - -class Solution(object): - def solve(self, cipher): - """ - Array, Math, Range - Range & Complementary Range - - [i , j] plus k == [i, +\infty] plus k with [j+1, +\infty] subtract k - - :param cipher: the cipher - """ - N, M, queries = cipher - - qry = [] - for query in queries: - qry.append((query[0], query[2])) - qry.append((query[1]+1, -query[2])) - - qry.sort(key=lambda x: (x[0], x[1])) - # qry.sort(key=lambda x: x[1]) # secondary attribute - - maxa = -1<<32 - cur = 0 - for q in qry: - cur += q[1] - maxa = max(maxa, cur) - - return maxa - - -if __name__=="__main__": - import sys - - f = open("1.in", "r") - # f = sys.stdin - N, M = map(int, f.readline().strip().split(' ')) - - queries = [] - for t in xrange(M): - # construct cipher - queries.append(map(int, f.readline().strip().split(' '))) - - cipher = N, M, queries - # solve - s = "%s\n"%(Solution().solve(cipher)) - print s, \ No newline at end of file +""" +You are given a list of size N, initialized with zeroes. You have to perform M queries on the list and output the +maximum of final values of all the N elements in the list. For every query, you are given three integers a, b and k and +you have to add value k to all the elements ranging from index a to b(both inclusive). + +Input Format +First line will contain two integers N and M separated by a single space. +Next M lines will contain three integers a, b and k separated by a single space. +Numbers in list are numbered from 1 to N. + +Output Format +A single line containing maximum value in the final list. +""" +__author__ = 'Danyang' + + +class Solution(object): + def solve(self, cipher): + """ + Array, Math, Range + Range & Complementary Range + + [i , j] plus k == [i, +\infty] plus k with [j+1, +\infty] subtract k + + :param cipher: the cipher + """ + N, M, queries = cipher + + qry = [] + for query in queries: + qry.append((query[0], query[2])) + qry.append((query[1] + 1, -query[2])) + + qry.sort(key=lambda x: (x[0], x[1])) + # qry.sort(key=lambda x: x[1]) # secondary attribute + + maxa = -1 << 32 + cur = 0 + for q in qry: + cur += q[1] + maxa = max(maxa, cur) + + return maxa + + +if __name__ == "__main__": + import sys + + f = open("1.in", "r") + # f = sys.stdin + N, M = map(int, f.readline().strip().split(' ')) + + queries = [] + for t in xrange(M): + # construct cipher + queries.append(map(int, f.readline().strip().split(' '))) + + cipher = N, M, queries + # solve + s = "%s\n" % (Solution().solve(cipher)) + print s, diff --git a/Almost Sorted.py b/Almost Sorted.py index 1137d38..0016d2e 100644 --- a/Almost Sorted.py +++ b/Almost Sorted.py @@ -1,90 +1,90 @@ -""" -Given an array with n elements, can you sort this array in ascending order using just one of the following operations? -You can perform only one of the following operations: -1. Swap two elements. -2. Reverse one sub-segment - -Input Format -The first line contains a single integer n, which indicates the size of the array. The next line contains n integers -seperated by spaces. - -n -d1 d2 ... dn -""" -__author__ = 'Danyang' - - -class Solution(object): - def solve(self, cipher): - """ - O(n lgn) brute force - O(n) scanning - - Array pointers - Logic thinking - Divide and Conquer rather than dealing with multiple things together - - A very good interview question - - main solution function - :param cipher: the cipher - """ - # find start - A = cipher - N = len(A) - start = 0 - while start+1=A[end+1]: - end += 1 - - if end==start+1: # swap - # find the item to be swapped - j = start+1 - while j+1A[end+1]: # even though reversed - return "no" - - return "yes\nreverse %d %d"%(start+1, end+1) - - -if __name__=="__main__": - import sys - - f = open("1.in", "r") - # f = sys.stdin - testcases = int(f.readline().strip()) - - - # construct cipher - cipher = map(int, f.readline().strip().split(' ')) - - # solve - s = "%s\n"%(Solution().solve(cipher)) - print s, \ No newline at end of file +""" +Given an array with n elements, can you sort this array in ascending order using just one of the following operations? +You can perform only one of the following operations: +1. Swap two elements. +2. Reverse one sub-segment + +Input Format +The first line contains a single integer n, which indicates the size of the array. The next line contains n integers +seperated by spaces. + +n +d1 d2 ... dn +""" +__author__ = 'Danyang' + + +class Solution(object): + def solve(self, cipher): + """ + O(n lgn) brute force + O(n) scanning + + Array pointers + Logic thinking + Divide and Conquer rather than dealing with multiple things together + + A very good interview question + + main solution function + :param cipher: the cipher + """ + # find start + A = cipher + N = len(A) + start = 0 + while start + 1 < N and A[start] <= A[start + 1]: + start += 1 + + # find test swap or reverse + end = start + 1 + while end + 1 < N and A[end] >= A[end + 1]: + end += 1 + + if end == start + 1: # swap + # find the item to be swapped + j = start + 1 + while j + 1 < N and A[j] < A[j + 1]: + j += 1 + + # not found + if j != start + 1 and j + 1 == N: # test cases: [3, 1], [3, 1, 2] + return "no" + # test tailing + i = j + 1 + while i + 1 < N: + if not A[i] < A[i + 1]: + return "no" + i += 1 + + if j != start + 1: + j += 1 + return "yes\nswap %d %d" % (start + 1, j + 1) + else: # reverse + # test tailing + i = end + 1 + while i + 1 < N: + if not A[i] < A[i + 1]: + return "no" + i += 1 + + if end + 1 < N and A[start] > A[end + 1]: # even though reversed + return "no" + + return "yes\nreverse %d %d" % (start + 1, end + 1) + + +if __name__ == "__main__": + import sys + + f = open("1.in", "r") + # f = sys.stdin + testcases = int(f.readline().strip()) + + + # construct cipher + cipher = map(int, f.readline().strip().split(' ')) + + # solve + s = "%s\n" % (Solution().solve(cipher)) + print s, diff --git a/Almost sorted interval.py b/Almost sorted interval.py index 28295dd..8e414fa 100644 --- a/Almost sorted interval.py +++ b/Almost sorted interval.py @@ -1,108 +1,110 @@ -""" -Shik loves sorted intervals. But currently he does not have enough time to sort all the numbers. So he decided to use -Almost sorted intervals. An Almost sorted interval is a consecutive subsequence in a sequence which satisfies the -following property: - -The first number is the smallest. -The last number is the largest. -Please help him count the number of almost sorted intervals in this permutation. - -Input Format -The first line contains an integer N. -The second line contains a permutation from 1 to N. -""" -__author__ = 'Danyang' - - -class Solution(object): - def solve(self, cipher): - """ - left[i] : the nearest (first) position left to i and with value larger than a[i] . - right[i] : the nearest (first) position right to i and with value smaller than a[i] . - use stack to find it. - - interval tree - - :param cipher: - :return: - """ - # TODO - - - def solve_time_out(self, cipher): - """ - chaining >, dp - similar to find Find Maximum Index Product - - L[i] is the nearest item on the right larger than A[i] - S[i] is the nearest item on the right smaller than A[i] - :type cipher: list - :param cipher - """ - A = cipher - L = [-1 for _ in A] - S = [-1 for _ in A] - for i in xrange(len(A)-2, -1, -1): - idx = i+1 - while idx!=-1: - if A[idx]A[i]: - idx = S[idx] - else: - break - S[i] = idx - - cnt = 0 - for i in xrange(len(A)): - cnt += 1 - l = L[i] - s = S[i] - while l!=-1 and (s==-1 or s>l): - cnt += 1 - l = L[l] - - return cnt - - def solve_error(self, cipher): - """ - sliding window, error. - :param cipher: the cipher - """ - A = cipher - N = len(A) - start = 0 - end = 1 # [0, 1) - cnt = 0 - while endA[end-1]: - end += 1 - else: - cnt += self.count(start, end) - start = end - end += 1 - - cnt += self.count(start, end) - return cnt - - def count(self, start, end): - l = end-start - return (l+1)*l/2 - -if __name__=="__main__": - import sys - f = open("0.in", "r") - # f = sys.stdin - N = int(f.readline().strip()) - - cipher = map(int, f.readline().strip().split(' ')) - - # solve - s = "%s\n"%(Solution().solve(cipher)) - print s, \ No newline at end of file +""" +Shik loves sorted intervals. But currently he does not have enough time to sort all the numbers. So he decided to use +Almost sorted intervals. An Almost sorted interval is a consecutive subsequence in a sequence which satisfies the +following property: + +The first number is the smallest. +The last number is the largest. +Please help him count the number of almost sorted intervals in this permutation. + +Input Format +The first line contains an integer N. +The second line contains a permutation from 1 to N. +""" +__author__ = 'Danyang' + + +class Solution(object): + def solve(self, cipher): + """ + left[i] : the nearest (first) position left to i and with value larger than a[i] . + right[i] : the nearest (first) position right to i and with value smaller than a[i] . + use stack to find it. + + interval tree + + :param cipher: + :return: + """ + # TODO + + + def solve_time_out(self, cipher): + """ + chaining >, dp + similar to find Find Maximum Index Product + + L[i] is the nearest item on the right larger than A[i] + S[i] is the nearest item on the right smaller than A[i] + :type cipher: list + :param cipher + """ + A = cipher + L = [-1 for _ in A] + S = [-1 for _ in A] + for i in xrange(len(A) - 2, -1, -1): + idx = i + 1 + while idx != -1: + if A[idx] < A[i]: + idx = L[idx] + else: + break + L[i] = idx + + idx = i + 1 + while idx != -1: + if A[idx] > A[i]: + idx = S[idx] + else: + break + S[i] = idx + + cnt = 0 + for i in xrange(len(A)): + cnt += 1 + l = L[i] + s = S[i] + while l != -1 and (s == -1 or s > l): + cnt += 1 + l = L[l] + + return cnt + + def solve_error(self, cipher): + """ + sliding window, error. + :param cipher: the cipher + """ + A = cipher + N = len(A) + start = 0 + end = 1 # [0, 1) + cnt = 0 + while end < N: + if A[end] > A[end - 1]: + end += 1 + else: + cnt += self.count(start, end) + start = end + end += 1 + + cnt += self.count(start, end) + return cnt + + def count(self, start, end): + l = end - start + return (l + 1) * l / 2 + + +if __name__ == "__main__": + import sys + + f = open("0.in", "r") + # f = sys.stdin + N = int(f.readline().strip()) + + cipher = map(int, f.readline().strip().split(' ')) + + # solve + s = "%s\n" % (Solution().solve(cipher)) + print s, diff --git a/Alternating Characters.py b/Alternating Characters.py index 66d2503..35e0a1c 100644 --- a/Alternating Characters.py +++ b/Alternating Characters.py @@ -21,16 +21,16 @@ def solve(self, cipher): ret = [lst[0]] cnt = 0 for i in xrange(1, len(lst)): - if lst[i]!=ret[-1]: + if lst[i] != ret[-1]: ret.append(lst[i]) else: cnt += 1 return cnt - -if __name__=="__main__": +if __name__ == "__main__": import sys + f = open("0.in", "r") # f = sys.stdin solution = Solution() @@ -41,5 +41,5 @@ def solve(self, cipher): cipher = f.readline().strip() # solve - s = "%s\n"%(solution.solve(cipher)) - print s, \ No newline at end of file + s = "%s\n" % (solution.solve(cipher)) + print s, diff --git a/Anagram.py b/Anagram.py index f7b1138..57d2d19 100644 --- a/Anagram.py +++ b/Anagram.py @@ -1,66 +1,66 @@ -""" -Sid is obsessed about reading short stories. Being a CS student, he is doing some interesting frequency analysis with -the books. He has two short story books. He chooses strings having length a from the first book and strings having -length b from the second one. The strings are such that the difference of length is <= 1 - -i.e. - -|a-b|<=1, where |x| represents the absolute value of x. -He believes that both the strings should be anagrams based on his experiment. Your challenge is to help him find the -minimum number of characters of the first string he needs to change to make it an anagram of the second string. He can -neither add a character nor delete a character from the first string. Only replacement of the original characters with -the new ones is allowed. - -Input Format - -The first line will contain an integer T representing the number of test cases. Each test case will contain a string -having length (a+b) which will be concatenation of both the strings described above in the problem. The string will only -contain small letters and there will be no spaces in the string. -""" -__author__ = 'Danyang' - - -class Solution(object): - def solve(self, cipher): - """ - main solution function - :param cipher: the cipher - """ - cipher = cipher[0] - length = len(cipher) - if length&1==1: - return -1 - str1 = cipher[:length/2] - str2 = cipher[length/2:] - # str1_lst.sort() - # str2_lst.sort() - # # simplified edit distance - # cum = 0 - # for i in xrange(length/2): - # if str1_lst[i]!=str2_lst[i]: - # cum += 1 - # return cum - - # bucket sort - bucket = [0 for _ in xrange(256)] - for elt in str1: - bucket[ord(elt)] += 1 - for elt in str2: - bucket[ord(elt)] -= 1 - return sum(filter(lambda x: x>0, bucket)) - - -if __name__=="__main__": - import sys - - f = open("1.in", "r") - # f = sys.stdin - testcases = int(f.readline().strip()) - - for t in xrange(testcases): - # construct cipher - cipher = f.readline().strip().split(' ') - - # solve - s = "%s\n"%(Solution().solve(cipher)) - print s, \ No newline at end of file +""" +Sid is obsessed about reading short stories. Being a CS student, he is doing some interesting frequency analysis with +the books. He has two short story books. He chooses strings having length a from the first book and strings having +length b from the second one. The strings are such that the difference of length is <= 1 + +i.e. + +|a-b|<=1, where |x| represents the absolute value of x. +He believes that both the strings should be anagrams based on his experiment. Your challenge is to help him find the +minimum number of characters of the first string he needs to change to make it an anagram of the second string. He can +neither add a character nor delete a character from the first string. Only replacement of the original characters with +the new ones is allowed. + +Input Format + +The first line will contain an integer T representing the number of test cases. Each test case will contain a string +having length (a+b) which will be concatenation of both the strings described above in the problem. The string will only +contain small letters and there will be no spaces in the string. +""" +__author__ = 'Danyang' + + +class Solution(object): + def solve(self, cipher): + """ + main solution function + :param cipher: the cipher + """ + cipher = cipher[0] + length = len(cipher) + if length & 1 == 1: + return -1 + str1 = cipher[:length / 2] + str2 = cipher[length / 2:] + # str1_lst.sort() + # str2_lst.sort() + # # simplified edit distance + # cum = 0 + # for i in xrange(length/2): + # if str1_lst[i]!=str2_lst[i]: + # cum += 1 + # return cum + + # bucket sort + bucket = [0 for _ in xrange(256)] + for elt in str1: + bucket[ord(elt)] += 1 + for elt in str2: + bucket[ord(elt)] -= 1 + return sum(filter(lambda x: x > 0, bucket)) + + +if __name__ == "__main__": + import sys + + f = open("1.in", "r") + # f = sys.stdin + testcases = int(f.readline().strip()) + + for t in xrange(testcases): + # construct cipher + cipher = f.readline().strip().split(' ') + + # solve + s = "%s\n" % (Solution().solve(cipher)) + print s, diff --git a/Angry Children.py b/Angry Children.py index 226a3ce..57f9d55 100644 --- a/Angry Children.py +++ b/Angry Children.py @@ -1,106 +1,106 @@ -""" -Bill Gates is on one of his philanthropic journeys to a village in Utopia. He has N packets of candies and would like to - distribute one packet to each of the K children in the village (each packet may contain different number of candies). - To avoid any fighting among the children, he would like to pick K out of N packets, such that unfairness is minimized. - -Suppose the K packets have (x1, x2, x3,....xk) candies in them, where xi denotes the number of candies in the ith -, then we define unfairness as - -max(x1,x2,...xk) - min(x1,x2,...xk) - -where max denotes the highest value amongst the elements, and min denotes the least value amongst the elements. Can you -figure out the minimum unfairness and print it? - -Input Format -The first line contains an integer N. -The second line contains an integer K. N lines follow. Each line contains an integer that denotes the candy in the ith -packet. -""" -__author__ = 'Danyang' - - -class Solution(object): - def solve_TLE(self, cipher): - """ - Naive approach - simulate combination. - - Sort and group as K - :param cipher: the cipher - """ - N, K, lst = cipher - lst.sort() - global_min = 1<<32-1 - for i in xrange(N-K): - seq = lst[i: i+K] - global_min = min(global_min, max(seq)-min(seq)) - - return global_min - - def solve_TLE2(self, cipher): - """ - Sliding window - - :param cipher: the cipher - """ - N, K, lst = cipher - lst.sort() - - seq = lst[0: K] - mini = min(seq) - maxa = max(seq) - global_min = maxa-mini - for i in xrange(K, N): - popped = seq.pop(0) - cur = lst[i] - seq.append(cur) - if popped!=mini: - mini = min(mini, cur) - else: - mini = min(seq) - if popped!=maxa: - maxa = max(maxa, cur) - else: - maxa = max(seq) - - global_min = min(global_min, maxa-mini) - - return global_min - - - def solve(self, cipher): - """ - Sliding window - O(n lgn) - - :param cipher: the cipher - """ - N, K, lst = cipher - lst.sort() - - mini = lst[0] - maxa = lst[K-1] - global_min = maxa-mini - for i in xrange(1, N-K): - mini = lst[i] - maxa = lst[i+K-1] - global_min = min(global_min, maxa-mini) - - return global_min - - -if __name__=="__main__": - import sys - - f = open("1.in", "r") - # f = sys.stdin - N = int(f.readline().strip()) - K = int(f.readline().strip()) - lst = [] - for t in xrange(N): - # construct cipher - lst.append(int(f.readline().strip())) - - cipher = (N, K, lst) - # solve - s = "%s\n"%(Solution().solve(cipher)) - print s, \ No newline at end of file +""" +Bill Gates is on one of his philanthropic journeys to a village in Utopia. He has N packets of candies and would like to + distribute one packet to each of the K children in the village (each packet may contain different number of candies). + To avoid any fighting among the children, he would like to pick K out of N packets, such that unfairness is minimized. + +Suppose the K packets have (x1, x2, x3,....xk) candies in them, where xi denotes the number of candies in the ith +, then we define unfairness as + +max(x1,x2,...xk) - min(x1,x2,...xk) + +where max denotes the highest value amongst the elements, and min denotes the least value amongst the elements. Can you +figure out the minimum unfairness and print it? + +Input Format +The first line contains an integer N. +The second line contains an integer K. N lines follow. Each line contains an integer that denotes the candy in the ith +packet. +""" +__author__ = 'Danyang' + + +class Solution(object): + def solve_TLE(self, cipher): + """ + Naive approach - simulate combination. + + Sort and group as K + :param cipher: the cipher + """ + N, K, lst = cipher + lst.sort() + global_min = 1 << 32 - 1 + for i in xrange(N - K): + seq = lst[i: i + K] + global_min = min(global_min, max(seq) - min(seq)) + + return global_min + + def solve_TLE2(self, cipher): + """ + Sliding window + + :param cipher: the cipher + """ + N, K, lst = cipher + lst.sort() + + seq = lst[0: K] + mini = min(seq) + maxa = max(seq) + global_min = maxa - mini + for i in xrange(K, N): + popped = seq.pop(0) + cur = lst[i] + seq.append(cur) + if popped != mini: + mini = min(mini, cur) + else: + mini = min(seq) + if popped != maxa: + maxa = max(maxa, cur) + else: + maxa = max(seq) + + global_min = min(global_min, maxa - mini) + + return global_min + + + def solve(self, cipher): + """ + Sliding window + O(n lgn) + + :param cipher: the cipher + """ + N, K, lst = cipher + lst.sort() + + mini = lst[0] + maxa = lst[K - 1] + global_min = maxa - mini + for i in xrange(1, N - K): + mini = lst[i] + maxa = lst[i + K - 1] + global_min = min(global_min, maxa - mini) + + return global_min + + +if __name__ == "__main__": + import sys + + f = open("1.in", "r") + # f = sys.stdin + N = int(f.readline().strip()) + K = int(f.readline().strip()) + lst = [] + for t in xrange(N): + # construct cipher + lst.append(int(f.readline().strip())) + + cipher = (N, K, lst) + # solve + s = "%s\n" % (Solution().solve(cipher)) + print s, diff --git a/AntiPalindromic Strings.py b/AntiPalindromic Strings.py index 7e6325e..15dcda4 100644 --- a/AntiPalindromic Strings.py +++ b/AntiPalindromic Strings.py @@ -7,37 +7,37 @@ """ __author__ = 'Danyang' -MOD = 10**9+7 +MOD = 10 ** 9 + 7 class Solution(object): def solve(self, cipher): """ Any palindrome, it has a sub-palindrome with length 2 or 3 pivoting at the center. - + To construct a palindrome, the 1st letter has M ways, the 2nd has (M-1) ways, subsequently, there are (M-2) ways to choose letters, since it should not be the same as the previous or pre-previous letter; - otherwise it will form a palindrom with either length 2 or 3. - + otherwise it will form a palindrom with either length 2 or 3. + Therefore, total = M*(M-1)*(M-2)*(M-2)*(M-2)... :param cipher: the cipher """ N, M = cipher s = M - if N>1: - s *= (M-1) - if N>2: - s *= pow(M-2, N-2, MOD) # s *= self._exp(M-2, N-2) + if N > 1: + s *= (M - 1) + if N > 2: + s *= pow(M - 2, N - 2, MOD) # s *= self._exp(M-2, N-2) s %= MOD - return s%MOD + return s % MOD - def _exp(self, a, b): + def _exp(self, a, b): """Alternative to built-in pow()""" ret = 1 b %= MOD - while b>0: - if b&1==0: + while b > 0: + if b & 1 == 0: b /= 2 a *= a a %= MOD @@ -48,8 +48,9 @@ def _exp(self, a, b): return ret -if __name__=="__main__": +if __name__ == "__main__": import sys + f = open("0.in", "r") # f = sys.stdin solution = Solution() @@ -60,5 +61,5 @@ def _exp(self, a, b): cipher = map(int, f.readline().strip().split(' ')) # solve - s = "%s\n"%(solution.solve(cipher)) + s = "%s\n" % (solution.solve(cipher)) print s, diff --git a/B'day Gift.py b/B'day Gift.py index 9e43fcb..e199c27 100644 --- a/B'day Gift.py +++ b/B'day Gift.py @@ -20,11 +20,12 @@ def solve(self, cipher): main solution function :param cipher: the cipher """ - return sum(cipher)/2.0 + return sum(cipher) / 2.0 -if __name__=="__main__": +if __name__ == "__main__": import sys + f = open("0.in", "r") # f = sys.stdin solution = Solution() @@ -36,5 +37,5 @@ def solve(self, cipher): cipher.append(int(f.readline().strip())) # solve - s = "%s\n"%(solution.solve(cipher)) - print s, \ No newline at end of file + s = "%s\n" % (solution.solve(cipher)) + print s, diff --git a/Bigger is Greater.py b/Bigger is Greater.py index 63a9382..26cd976 100644 --- a/Bigger is Greater.py +++ b/Bigger is Greater.py @@ -21,30 +21,30 @@ def solve(self, cipher): A = map(ord, A) n = len(A) - a = -1 - for i in xrange(n-1, 0, -1): - if A[i-1]A[a]: + for i in xrange(n - 1, a, -1): + if A[i] > A[a]: b = i break else: return "no answer" A[a], A[b] = A[b], A[a] # swap - A = A[:a+1]+A[n-1:a:-1] # reverse + A = A[:a + 1] + A[n - 1:a:-1] # reverse return "".join(map(chr, A)) -if __name__=="__main__": +if __name__ == "__main__": import sys + f = open("1.in", "r") # f = sys.stdin solution = Solution() @@ -55,5 +55,5 @@ def solve(self, cipher): cipher = f.readline().strip() # solve - s = "%s\n"%(solution.solve(cipher)) - print s, \ No newline at end of file + s = "%s\n" % (solution.solve(cipher)) + print s, diff --git a/Building a List.py b/Building a List.py index 428edd9..bbfb942 100644 --- a/Building a List.py +++ b/Building a List.py @@ -1,52 +1,52 @@ -""" -Problem Statement - -Chan has decided to make a list of all possible combinations of letters of a given string S. If there are two strings -with the same set of characters, print the lexicographically smallest arrangement of the two strings. - -abc acb cab bac bca -all the above strings' lexicographically smallest string is abc. - -Each character in the string S is unique. Your task is to print the entire list of Chan's in lexicographic order. - -for string abc, the list in lexicographic order is given below - -a ab abc ac b bc c -""" -__author__ = 'Danyang' - - -class Solution(object): - def solve(self, cipher): - """ - main solution function - :param cipher: the cipher - """ - s = cipher - s = "".join(sorted(list(s))) - result = [] - self.dfs(s, "", result) - return "\n".join(result[1:]) - - def dfs(self, seq, cur, result): - result.append(cur) - if seq: - for i in xrange(len(seq)): - self.dfs(seq[i+1:], cur+seq[i], result) - - -if __name__=="__main__": - import sys - - f = open("1.in", "r") - # f = sys.stdin - testcases = int(f.readline().strip()) - - for t in xrange(testcases): - # construct cipher - N = int(f.readline().strip()) - cipher = f.readline().strip() - - # solve - s = "%s\n"%(Solution().solve(cipher)) - print s, \ No newline at end of file +""" +Problem Statement + +Chan has decided to make a list of all possible combinations of letters of a given string S. If there are two strings +with the same set of characters, print the lexicographically smallest arrangement of the two strings. + +abc acb cab bac bca +all the above strings' lexicographically smallest string is abc. + +Each character in the string S is unique. Your task is to print the entire list of Chan's in lexicographic order. + +for string abc, the list in lexicographic order is given below + +a ab abc ac b bc c +""" +__author__ = 'Danyang' + + +class Solution(object): + def solve(self, cipher): + """ + main solution function + :param cipher: the cipher + """ + s = cipher + s = "".join(sorted(list(s))) + result = [] + self.dfs(s, "", result) + return "\n".join(result[1:]) + + def dfs(self, seq, cur, result): + result.append(cur) + if seq: + for i in xrange(len(seq)): + self.dfs(seq[i + 1:], cur + seq[i], result) + + +if __name__ == "__main__": + import sys + + f = open("1.in", "r") + # f = sys.stdin + testcases = int(f.readline().strip()) + + for t in xrange(testcases): + # construct cipher + N = int(f.readline().strip()) + cipher = f.readline().strip() + + # solve + s = "%s\n" % (Solution().solve(cipher)) + print s, diff --git a/Bus Station.py b/Bus Station.py index 1f90811..3f60249 100644 --- a/Bus Station.py +++ b/Bus Station.py @@ -1,74 +1,74 @@ -# -*- coding: utf-8 -*- -""" -There are n groups of friends, and each group is numbered from 1 to n. The ith group contains ai people. - -They live near a bus stop, and only a single bus operates on this route. An empty bus arrives at the bus stop and all -the groups want to travel by the bus. - -However, group of friends do not want to get separated. So they enter the bus only if the bus can carry the entire -group. - -Moreover, the groups do not want to change their relative positioning while travelling. In other words, group 3 cannot -travel by bus, unless group 1 and group 2 have either (a) already traveled by the bus in the previous trip or (b) they -are also sitting inside the bus at present. - -You are given that a bus of size x can carry x people simultaneously. - -Find the size x of the bus so that (1) the bus can transport all the groups and (2) every time when the bus starts from -the bus station, there is no empty space in the bus (i.e. the total number of people present inside the bus is equal to -x)? - -Input Format -The first line contains an integer n (1≤n≤105). The second line contains n space-separated integers a1,a2,…,an -(1≤ai≤104). -""" -__author__ = 'Danyang' - - -class Solution(object): - def solve(self, cipher): - """ - sum - brute force - how to improve? - prune - can we do better? - Algorithm: - rather than simulate the bus trip, consider the math model - 1k, 2k, 3k, 4k, 5k - - :type cipher: list - :param cipher: the cipher - """ - N = len(cipher) - sum_set = set() - s = 0 - for val in cipher: - s += val - sum_set.add(s) - - result = [] - for k in sum_set: - if s%k==0: - j = 1 - while jup and i>1000: + if i > up and i > 1000: break - s += float(e)/2**(i+1) + s += float(e) / 2 ** (i + 1) return int(math.ceil(s)) def solve(self, cipher): @@ -49,13 +50,14 @@ def solve(self, cipher): """ N, H = cipher mini = 0 - for i in xrange(N-1, -1, -1): - mini = (mini+H[i]+1)/2 # ceil, but better than float version of math.ceil + for i in xrange(N - 1, -1, -1): + mini = (mini + H[i] + 1) / 2 # ceil, but better than float version of math.ceil return mini -if __name__=="__main__": +if __name__ == "__main__": import sys + f = open("1.in", "r") # f = sys.stdin solution = Solution() @@ -63,5 +65,5 @@ def solve(self, cipher): H = map(int, f.readline().strip().split(' ')) cipher = N, H # solve - s = "%s\n"%(solution.solve(cipher)) - print s, \ No newline at end of file + s = "%s\n" % (solution.solve(cipher)) + print s, diff --git a/Circle City.py b/Circle City.py index 8c8d124..3ad8847 100644 --- a/Circle City.py +++ b/Circle City.py @@ -1,69 +1,69 @@ -""" -Problem Statement - -Roy lives in a city that is circular in shape on a 2D plane. The city center is located at origin (0,0) and it has -suburbs lying on the lattice points (points with integer coordinates). The city Police Department Headquarters can only -protect those suburbs which are located strictly inside the city. The suburbs located on the border of the city are -still unprotected. So the police department decides to build at most k additional police stations at some suburbs. Each -of these police stations can protect the suburb it is located in. - -Given the radius of the city, Roy has to determine if it is possible to protect all the suburbs. - -Input Format -The first line of input contains integer t, t testcases follow. -Each of next t lines contains two space separated integers: r, the square of the radius of the city and k, the maximum -number of police stations the headquarters is willing to build. -""" -__author__ = 'Danyang' - - -class Solution(object): - def solve(self, cipher): - """ - Boarder detection - Binary search for coordinates. - - Python time out, use C++ instead. - :param cipher: the cipher - """ - r2, k = cipher - - required = 0 - r = r2**0.5 - - for x in xrange(0, int(r)+1): - # binary search - low = 0 - high = int(r)+1 - while low<=high: - mid = (low+high)/2 - if x*x+mid*mid==r2: - if mid==0 or x==0: - required += 2 - else: - required += 4 - if required>k: return "impossible" - break - elif x*x+mid*midk: return "impossible" - return "possible" - - -if __name__=="__main__": - import sys - - f = open("1.in", "r") - # f = sys.stdin - testcases = int(f.readline().strip()) - - for t in xrange(testcases): - # construct cipher - cipher = map(int, f.readline().strip().split(' ')) - - # solve - s = "%s\n"%(Solution().solve(cipher)) - print s, \ No newline at end of file +""" +Problem Statement + +Roy lives in a city that is circular in shape on a 2D plane. The city center is located at origin (0,0) and it has +suburbs lying on the lattice points (points with integer coordinates). The city Police Department Headquarters can only +protect those suburbs which are located strictly inside the city. The suburbs located on the border of the city are +still unprotected. So the police department decides to build at most k additional police stations at some suburbs. Each +of these police stations can protect the suburb it is located in. + +Given the radius of the city, Roy has to determine if it is possible to protect all the suburbs. + +Input Format +The first line of input contains integer t, t testcases follow. +Each of next t lines contains two space separated integers: r, the square of the radius of the city and k, the maximum +number of police stations the headquarters is willing to build. +""" +__author__ = 'Danyang' + + +class Solution(object): + def solve(self, cipher): + """ + Boarder detection + Binary search for coordinates. + + Python time out, use C++ instead. + :param cipher: the cipher + """ + r2, k = cipher + + required = 0 + r = r2 ** 0.5 + + for x in xrange(0, int(r) + 1): + # binary search + low = 0 + high = int(r) + 1 + while low <= high: + mid = (low + high) / 2 + if x * x + mid * mid == r2: + if mid == 0 or x == 0: + required += 2 + else: + required += 4 + if required > k: return "impossible" + break + elif x * x + mid * mid < r2: + low = mid + 1 + else: + high = mid - 1 + + if required > k: return "impossible" + return "possible" + + +if __name__ == "__main__": + import sys + + f = open("1.in", "r") + # f = sys.stdin + testcases = int(f.readline().strip()) + + for t in xrange(testcases): + # construct cipher + cipher = map(int, f.readline().strip().split(' ')) + + # solve + s = "%s\n" % (Solution().solve(cipher)) + print s, diff --git a/Clique.py b/Clique.py index 6039ef3..67f8802 100644 --- a/Clique.py +++ b/Clique.py @@ -1,66 +1,65 @@ -""" -A clique in a graph is set of nodes such that there is an edge between any two distinct nodes in the set. It is well -known that finding the largest clique in a graph is a computationally tough problem and no polynomial time algorithm -exists for it. However, you wonder what is the minimum size of the largest clique in any graph with N nodes and M edges. - -Input Format -The first line contains T the number of test cases. Each of the next T lines contain 2 integers : N, M -""" -__author__ = 'Danyang' - - -class Solution(object): - def solve(self, cipher): - """ - Turan's Graph: - - :param cipher: the cipher - """ - N, M = cipher - # K_{r+1} free - # r = 2 - # edge_cnt = 0 - # while edge_cntM - low = 0 - high = N - while low+1M + low = 0 + high = N + while low + 1 < high: + mid = (low + high) / 2 + r = self.Turan(N, mid) + + if r < M: + low = mid + else: + high = mid + return high + + def Turan(self, n, r): + """ + http://en.wikipedia.org/wiki/Tur%C3%A1n_graph + """ + return 0.5 * (n ** 2 - (n % r) * (n / r + 1) ** 2 - (r - (n % r)) * (n / r) ** 2) + + +if __name__ == "__main__": + import sys + + f = open("1.in", "r") + # f = sys.stdin + testcases = int(f.readline().strip()) + + for t in xrange(testcases): + # construct cipher + cipher = map(int, f.readline().strip().split(' ')) + + # solve + s = "%s\n" % (Solution().solve(cipher)) + print s, diff --git a/Closest Number.py b/Closest Number.py index b9bd8c9..9529efd 100644 --- a/Closest Number.py +++ b/Closest Number.py @@ -1,57 +1,57 @@ -# -*- coding: utf-8 -*- -""" -Problem Statement - -You are given 3 numbers a, b and x. You need to output the multiple of x which is closest to ab. If more than one answer - exists , display the smallest one. - -Input Format -The first line contains T, the number of testcases. -T lines follow, each line contains 3 space separated integers (a, b and x respectively) - -Output Format -For each test case , output the multiple of x which is closest to ab - -Constraints -1 ≤ T ≤ 105 -1 ≤ x ≤ 109 -0 < ab ≤ 109 -1 ≤ a ≤ 109 --109 ≤ b ≤ 109 -""" -__author__ = 'Danyang' - - -class Solution(object): - def solve(self, cipher): - """ - main solution function - :param cipher: the cipher - """ - a, b, x = cipher - if a>1: - result = int((a**b)/float(x)+0.5)*x - else: - result = 1 - if result!=int(result): - if result>0.5 and x==1: - return 1 - else: - return 0 - return result - - -if __name__=="__main__": - import sys - - f = open("1.in", "r") - # f = sys.stdin - testcases = int(f.readline().strip()) - - for t in xrange(testcases): - # construct cipher - cipher = map(int, f.readline().strip().split(' ')) - - # solve - s = "%s\n"%(Solution().solve(cipher)) - print s, \ No newline at end of file +# -*- coding: utf-8 -*- +""" +Problem Statement + +You are given 3 numbers a, b and x. You need to output the multiple of x which is closest to ab. If more than one answer + exists , display the smallest one. + +Input Format +The first line contains T, the number of testcases. +T lines follow, each line contains 3 space separated integers (a, b and x respectively) + +Output Format +For each test case , output the multiple of x which is closest to ab + +Constraints +1 ≤ T ≤ 105 +1 ≤ x ≤ 109 +0 < ab ≤ 109 +1 ≤ a ≤ 109 +-109 ≤ b ≤ 109 +""" +__author__ = 'Danyang' + + +class Solution(object): + def solve(self, cipher): + """ + main solution function + :param cipher: the cipher + """ + a, b, x = cipher + if a > 1: + result = int((a ** b) / float(x) + 0.5) * x + else: + result = 1 + if result != int(result): + if result > 0.5 and x == 1: + return 1 + else: + return 0 + return result + + +if __name__ == "__main__": + import sys + + f = open("1.in", "r") + # f = sys.stdin + testcases = int(f.readline().strip()) + + for t in xrange(testcases): + # construct cipher + cipher = map(int, f.readline().strip().split(' ')) + + # solve + s = "%s\n" % (Solution().solve(cipher)) + print s, diff --git a/Closest Numbers.py b/Closest Numbers.py index 7031ad0..7925346 100644 --- a/Closest Numbers.py +++ b/Closest Numbers.py @@ -1,50 +1,50 @@ -""" -Problem Statement - -Sorting is often useful as the first step in many different tasks. The most common task is to make finding things -easier, but there are other uses also. - -Challenge -Given a list of unsorted numbers, can you find the numbers that have the smallest absolute difference between them? If -there are multiple pairs, find them all. -""" -__author__ = 'Danyang' - - -class Solution(object): - def solve(self, cipher): - """ - main solution function - :param cipher: the cipher - """ - N, A = cipher - A.sort() - - diff = 1<<31 - lst = [] - for i in xrange(N-1): - b = A[i+1] - a = A[i] - if abs(a-b)=n: - self.count[(n, k)] = 1 - else: - self.count[(n, k)] = 0 - else: - i = 0 - cnt = 0 - while i<=self.A[k] and i*self.coinage[k]<=n: - cnt += self.get_count(n-i*self.coinage[k], k-1) - i += 1 - self.count[(n, k)] = cnt - - return self.count[(n, k)] - - - - - -if __name__=="__main__": - import sys - f = open("1.in", "r") - # f = sys.stdin - testcases = int(f.readline().strip()) - - for t in xrange(testcases): - # construct cipher - target = int(f.readline().strip()) - lst = map(int, f.readline().strip().split(' ')) - cipher = target, lst - # solve - s = "%s\n"%(Solution().solve(cipher)) - print s, \ No newline at end of file +# -*- coding: utf-8 -*- +""" +Problem Statement + +The Indian bank issues coins in 4 denominations, ₹1, ₹2, ₹5 and ₹10. + +Given a limited supply of each of the above denominations, in how many ways can you sum them up to a total of ₹N? + +Input Format +The first line contains an integer T (number of testcases). Each testcase contains 2 lines. The first line contains +integer N (sum to be achieved) +A, B, C and D in the next line, each representing the number of ₹1, ₹2, ₹5 and ₹10 coins respectively. + +Output Format +Output the number of ways in which we can achieve the sum N. +""" +__author__ = 'Danyang' + + +class Solution_TLE(object): + def __init__(self): + self.coinage = [10, 5, 2, 1] + + def solve(self, cipher): + """ + branch & bound + :param cipher: the cipher + """ + target, lst = cipher + lst.reverse() + result = [0] + self.dfs(lst, target, result) + return result[0] + + def dfs(self, seq, remaining, result): + if remaining < 0: + return + if remaining == 0: + result[0] += 1 + return + + bound = 0 + for i in xrange(4): + bound += seq[i] * self.coinage[i] + if bound < remaining: + return + + for j in xrange(4): + for i in xrange(seq[j]): + remaining -= (i + 1) * self.coinage[j] + self.dfs([0] * (j + 1) + seq[j + 1:], remaining, result) + remaining += (i + 1) * self.coinage[j] + + +class Solution(object): + def __init__(self): + self.coinage = [1, 2, 5, 10] + self.count = {} + self.A = None + + def solve(self, cipher): + """ + dp + :param cipher: the cipher + """ + target, self.A = cipher + return self.get_count(target, 3) + + def get_count(self, n, k): + """ + algorithm top-down dp + bottom-up dp: https://github.com/derekhh/HackerRank/blob/master/coinage.cpp + :param seq: + :param n: target + :param k: current examining coin + """ + if (n, k) not in self.count: + if k == 0: + if n % self.coinage[k] == 0 and self.coinage[k] * self.A[k] >= n: + self.count[(n, k)] = 1 + else: + self.count[(n, k)] = 0 + else: + i = 0 + cnt = 0 + while i <= self.A[k] and i * self.coinage[k] <= n: + cnt += self.get_count(n - i * self.coinage[k], k - 1) + i += 1 + self.count[(n, k)] = cnt + + return self.count[(n, k)] + + +if __name__ == "__main__": + import sys + + f = open("1.in", "r") + # f = sys.stdin + testcases = int(f.readline().strip()) + + for t in xrange(testcases): + # construct cipher + target = int(f.readline().strip()) + lst = map(int, f.readline().strip().split(' ')) + cipher = target, lst + # solve + s = "%s\n" % (Solution().solve(cipher)) + print s, diff --git a/Common Child.py b/Common Child.py index 7445947..ad21895 100644 --- a/Common Child.py +++ b/Common Child.py @@ -1,68 +1,68 @@ -""" -Given two strings a and b of equal length, what's the longest string (S) that can be constructed such that S is a child -of both a and b. - -A string x is said to be a child of a string y, if x can be formed by deleting 0 or more characters from y - -Input format - -Two strings a and b with a newline separating them -""" -__author__ = 'Danyang' - - -class Solution(object): - def solve_error(self, cipher): - """ - dp - - error transition: - dp[i][j] = dp[i-1][j] + 1 if a[i]==b[j] - dp[i][j] = max(dp[i][j-1], dp[i-1][j]) if a[i]!=b[j] - :param cipher: the cipher - """ - a, b = cipher - m = len(a) - n = len(b) - dp = [[0 for _ in xrange(n+1)] for _ in xrange(m+1)] - for i in xrange(1, m+1): - for j in xrange(1, n+1): - if a[i-1]==b[j-1]: - dp[i][j] = min(dp[i][j-1], dp[i-1][j])+1 - else: - dp[i][j] = max(dp[i][j-1], dp[i-1][j]) # superset - return dp[-1][-1] - - def solve(self, cipher): - """ - dp - - dp longest common sequence - dp[i][j] = dp[i-1][j-1] + 1 if a[i]==b[j] - dp[i][j] = max(dp[i][j-1], dp[i-1][j]) if a[i]!=b[j] - :param cipher: the cipher - """ - a, b = cipher - m = len(a) - n = len(b) - dp = [[0 for _ in xrange(n+1)] for _ in xrange(m+1)] - for i in xrange(1, m+1): - for j in xrange(1, n+1): - if a[i-1]==b[j-1]: - dp[i][j] = dp[i-1][j-1]+1 - else: - dp[i][j] = max(dp[i][j-1], dp[i-1][j]) # superset - return dp[-1][-1] - - -if __name__=="__main__": - import sys - - f = open("1.in", "r") - # f = sys.stdin - cipher = [] - cipher.append(f.readline().strip()) - cipher.append(f.readline().strip()) - - s = "%s\n"%(Solution().solve(cipher)) - print s, \ No newline at end of file +""" +Given two strings a and b of equal length, what's the longest string (S) that can be constructed such that S is a child +of both a and b. + +A string x is said to be a child of a string y, if x can be formed by deleting 0 or more characters from y + +Input format + +Two strings a and b with a newline separating them +""" +__author__ = 'Danyang' + + +class Solution(object): + def solve_error(self, cipher): + """ + dp + + error transition: + dp[i][j] = dp[i-1][j] + 1 if a[i]==b[j] + dp[i][j] = max(dp[i][j-1], dp[i-1][j]) if a[i]!=b[j] + :param cipher: the cipher + """ + a, b = cipher + m = len(a) + n = len(b) + dp = [[0 for _ in xrange(n + 1)] for _ in xrange(m + 1)] + for i in xrange(1, m + 1): + for j in xrange(1, n + 1): + if a[i - 1] == b[j - 1]: + dp[i][j] = min(dp[i][j - 1], dp[i - 1][j]) + 1 + else: + dp[i][j] = max(dp[i][j - 1], dp[i - 1][j]) # superset + return dp[-1][-1] + + def solve(self, cipher): + """ + dp + + dp longest common sequence + dp[i][j] = dp[i-1][j-1] + 1 if a[i]==b[j] + dp[i][j] = max(dp[i][j-1], dp[i-1][j]) if a[i]!=b[j] + :param cipher: the cipher + """ + a, b = cipher + m = len(a) + n = len(b) + dp = [[0 for _ in xrange(n + 1)] for _ in xrange(m + 1)] + for i in xrange(1, m + 1): + for j in xrange(1, n + 1): + if a[i - 1] == b[j - 1]: + dp[i][j] = dp[i - 1][j - 1] + 1 + else: + dp[i][j] = max(dp[i][j - 1], dp[i - 1][j]) # superset + return dp[-1][-1] + + +if __name__ == "__main__": + import sys + + f = open("1.in", "r") + # f = sys.stdin + cipher = [] + cipher.append(f.readline().strip()) + cipher.append(f.readline().strip()) + + s = "%s\n" % (Solution().solve(cipher)) + print s, diff --git a/Connected Cell in a Grid.py b/Connected Cell in a Grid.py index 235a2e0..c8fee07 100644 --- a/Connected Cell in a Grid.py +++ b/Connected Cell in a Grid.py @@ -26,7 +26,7 @@ def solve(self, cipher): visited = [[False for _ in xrange(n)] for _ in xrange(m)] for i in xrange(m): for j in xrange(n): - if not visited[i][j] and mat[i][j]==1: + if not visited[i][j] and mat[i][j] == 1: self.cur_area = 0 self.dfs(visited, mat, i, j, m, n) @@ -38,14 +38,15 @@ def dfs(self, visited, mat, i, j, m, n): self.max = max(self.max, self.cur_area) for dir in self.dirs: - i1 = i+dir[0] - j1 = j+dir[1] - if 0<=i11: - cnt += 1 - self.logger.debug("Wand@"+str(cur)) - if cnt>K: - return "Oops!" - - self.logger.debug("cnt: %d, K: %d"%(cnt, K)) - if cnt==K: # exactly K times - return "Impressed" - else: - return "Oops!" - - -if __name__=="__main__": - f = open("1.in", "r") - # f = sys.stdin - testcases = int(f.readline().strip()) - - for t in xrange(testcases): - # construct cipher - M, N = map(int, f.readline().strip().split(' ')) - matrix = [] - for _ in xrange(M): - matrix.append(list(f.readline().strip())) - K = int(f.readline().strip()) - cipher = M, N, matrix, K - - # solve - s = "%s\n"%(Solution().solve(cipher)) - print s, \ No newline at end of file +__author__ = 'Danyang' +import logging +import sys + + +class Solution(object): + @property + def logger(self): + lgr = logging.getLogger(__name__) + lgr.setLevel(logging.CRITICAL) + if not lgr.handlers: + ch = logging.StreamHandler(sys.stdout) + ch.setLevel(logging.DEBUG) + ch.setFormatter(logging.Formatter('%(levelname)s - %(message)s')) + lgr.addHandler(ch) + return lgr + + def solve(self, cipher): + """ + bfs + + attention to the usage of unvisited array + :param cipher: the cipher + """ + dirs = ((1, 0), (-1, 0), (0, 1), (0, -1)) + M, N, matrix, K = cipher + + start = None + end = None + for i in xrange(M): + for j in xrange(N): + if matrix[i][j] == "M": + start = (i, j) + elif matrix[i][j] == "*": + end = (i, j) + + pi = [[None for _ in xrange(N)] for _ in xrange(M)] + visited = [[False for _ in xrange(N)] for _ in xrange(M)] + + visited[start[0]][start[1]] = True + q = [start] + ended = False + while q and not ended: + l = len(q) + for i in xrange(l): + cur = q[i] + for dir in dirs: + r = cur[0] + dir[0] + c = cur[1] + dir[1] + if 0 <= r < M and 0 <= c < N and not visited[r][c]: + visited[r][c] = True + if matrix[r][c] in (".", "*"): + pi[r][c] = cur + q.append((r, c)) + if matrix[r][c] == "*": + ended = True + q = q[l:] + + if not ended: + return "not found" + + path = [end] + cur = end + while cur != start: + cur = pi[cur[0]][cur[1]] + path.append(cur) + + path.reverse() + self.logger.debug(str(path)) + cnt = 0 + visited = [[False for _ in xrange(N)] for _ in xrange(M)] + for cur in path[:-1]: + dir_cnt = 0 + visited[cur[0]][cur[1]] = True + for dir in dirs: + r = cur[0] + dir[0] + c = cur[1] + dir[1] + if 0 <= r < M and 0 <= c < N: + if matrix[r][c] in (".", "*") and not visited[r][c]: + dir_cnt += 1 + if dir_cnt > 1: + cnt += 1 + self.logger.debug("Wand@" + str(cur)) + if cnt > K: + return "Oops!" + + self.logger.debug("cnt: %d, K: %d" % (cnt, K)) + if cnt == K: # exactly K times + return "Impressed" + else: + return "Oops!" + + +if __name__ == "__main__": + f = open("1.in", "r") + # f = sys.stdin + testcases = int(f.readline().strip()) + + for t in xrange(testcases): + # construct cipher + M, N = map(int, f.readline().strip().split(' ')) + matrix = [] + for _ in xrange(M): + matrix.append(list(f.readline().strip())) + K = int(f.readline().strip()) + cipher = M, N, matrix, K + + # solve + s = "%s\n" % (Solution().solve(cipher)) + print s, diff --git a/Counter game.py b/Counter game.py index 6e66725..3360d56 100644 --- a/Counter game.py +++ b/Counter game.py @@ -1,59 +1,59 @@ -""" -Louise and Richard play a game. They have a counter set to N. Louise gets the first turn and the turns alternate -thereafter. In the game, they perform the following operations. - -If N is not a power of 2, they reduce the counter by the largest power of 2 less than N. -If N is a power of 2, they reduce the counter by half of N. -The resultant value is the new N which is again used for subsequent operations. -The game ends when the counter reduces to 1, i.e., N == 1, and the last person to make a valid move wins. - -Given N, your task is to find the winner of the game. - -Update If they set counter to 1, Richard wins, because its Louise' turn and she cannot make a move. - -Input Format -The first line contains an integer T, the number of testcases. -T lines follow. Each line contains N, the initial number set in the counter. -""" -__author__ = 'Danyang' - - -class Solution(object): - def solve(self, cipher): - """ - main solution function - :param cipher: the cipher - """ - N = cipher - turn = 0 - while N>1: - turn += 1 - if N&(N-1)==0: - N /= 2 - else: - num = 1 - while num>= 1 - N -= num - - if turn&1==0: - return "Richard" - else: - return "Louise" - - -if __name__=="__main__": - import sys - - f = open("1.in", "r") - # f = sys.stdin - testcases = int(f.readline().strip()) - - for t in xrange(testcases): - # construct cipher - cipher = int(f.readline().strip()) - - # solve - s = "%s\n"%(Solution().solve(cipher)) - print s, \ No newline at end of file +""" +Louise and Richard play a game. They have a counter set to N. Louise gets the first turn and the turns alternate +thereafter. In the game, they perform the following operations. + +If N is not a power of 2, they reduce the counter by the largest power of 2 less than N. +If N is a power of 2, they reduce the counter by half of N. +The resultant value is the new N which is again used for subsequent operations. +The game ends when the counter reduces to 1, i.e., N == 1, and the last person to make a valid move wins. + +Given N, your task is to find the winner of the game. + +Update If they set counter to 1, Richard wins, because its Louise' turn and she cannot make a move. + +Input Format +The first line contains an integer T, the number of testcases. +T lines follow. Each line contains N, the initial number set in the counter. +""" +__author__ = 'Danyang' + + +class Solution(object): + def solve(self, cipher): + """ + main solution function + :param cipher: the cipher + """ + N = cipher + turn = 0 + while N > 1: + turn += 1 + if N & (N - 1) == 0: + N /= 2 + else: + num = 1 + while num < N: + num <<= 1 + num >>= 1 + N -= num + + if turn & 1 == 0: + return "Richard" + else: + return "Louise" + + +if __name__ == "__main__": + import sys + + f = open("1.in", "r") + # f = sys.stdin + testcases = int(f.readline().strip()) + + for t in xrange(testcases): + # construct cipher + cipher = int(f.readline().strip()) + + # solve + s = "%s\n" % (Solution().solve(cipher)) + print s, diff --git a/Cut the sticks.py b/Cut the sticks.py index 9d6f73e..c81b195 100644 --- a/Cut the sticks.py +++ b/Cut the sticks.py @@ -1,42 +1,42 @@ -""" -Problem Statement - -You are given N sticks, where each stick is of positive integral length. A cut operation is performed on the sticks such -that all of them are reduced by the length of the smallest stick. - -Suppose we have 6 sticks of length -""" -__author__ = 'Danyang' - - -class Solution(object): - def solve(self, cipher): - """ - main solution function - :param cipher: the cipher - """ - N, A = cipher - A.sort() - - result = [] - while A: - result.append(len(A)) - A = map(lambda x: x-A[0], A) - A = filter(lambda x: x>0, A) - - return "\n".join(map(str, result)) - - -if __name__=="__main__": - import sys - - f = open("1.in", "r") - # f = sys.stdin - solution = Solution() - N = int(f.readline().strip()) - A = map(int, f.readline().strip().split(' ')) - cipher = N, A - - # solve - s = "%s\n"%(solution.solve(cipher)) - print s, \ No newline at end of file +""" +Problem Statement + +You are given N sticks, where each stick is of positive integral length. A cut operation is performed on the sticks such +that all of them are reduced by the length of the smallest stick. + +Suppose we have 6 sticks of length +""" +__author__ = 'Danyang' + + +class Solution(object): + def solve(self, cipher): + """ + main solution function + :param cipher: the cipher + """ + N, A = cipher + A.sort() + + result = [] + while A: + result.append(len(A)) + A = map(lambda x: x - A[0], A) + A = filter(lambda x: x > 0, A) + + return "\n".join(map(str, result)) + + +if __name__ == "__main__": + import sys + + f = open("1.in", "r") + # f = sys.stdin + solution = Solution() + N = int(f.readline().strip()) + A = map(int, f.readline().strip().split(' ')) + cipher = N, A + + # solve + s = "%s\n" % (solution.solve(cipher)) + print s, diff --git a/Cut the tree.py b/Cut the tree.py index 5635ac4..7ded350 100644 --- a/Cut the tree.py +++ b/Cut the tree.py @@ -1,208 +1,208 @@ -# -*- coding: utf-8 -*- -""" -Atul is into graph theory, and he is learning about trees nowadays. He observed that the removal of an edge from a given -tree T will result in formation of two separate trees T1 and T2. - -Each vertex of the tree T is assigned a positive integer. Your task is to remove an edge, such that, the *Tree_diff* of -the resultant trees is minimized. *Tree_diff* is defined as - - F(T) = Sum of numbers written on each vertex of a Tree T - Tree_diff(T) = abs(F(T1) - F(T2)) -Input Format -The first line will contain an integer N, i.e., the number of vertices in the tree. -The next line will contain N integers separated by a single space, i.e., the values assigned to each of the vertices. -The next (N-1) lines contain pair of integers separated by a single space and denote the edges of the tree. -In the above input, the vertices are numbered from 1 to N. - -Output Format -A single line containing the minimum value of *Tree_diff*. - -Constraints -3 ≤ N ≤ 105 -1 ≤ number written on each vertex ≤ 1001 - -Sample Input - -6 -100 200 100 500 100 600 -1 2 -2 3 -2 5 -4 5 -5 6 -Sample Output - -400 -""" -__author__ = 'Danyang' - - -class TreeNode(object): - def __init__(self, item): - self.item = item - self.tree_sum = None - self.left = None - self.right = None - - def __repr__(self): - return repr(self.item) - - -class Solution_error(object): - def solve(self, cipher): - """ - it should be graph theory rather than tree - - bought test case #5 - :param cipher: the cipher - """ - root = self.construct_tree(cipher) - total = self.get_tree_sum(root) - mini = [1<<32] # primitive is pass by value thus put it into array - self.dfs(root, total, mini) - return mini[0] - - def dfs(self, root, total, mini): - """ - pre-order - """ - if not root: - return - - mini[0] = min(mini[0], abs(total-root.tree_sum-root.tree_sum)) - self.dfs(root.left, total, mini) - self.dfs(root.right, total, mini) - - - def construct_tree(self, cipher): - """ - Hard part, the connection not necessarily from parent to child - errors may occur here due to the edge - """ - N, nodes, rls = cipher - lst = [TreeNode(val) for val in nodes] - # rls.sort(key=lambda x: x[1]) # secondary - # rls.sort(key=lambda x: x[0]) - rls = map(lambda x: [x[0]-1, x[1]-1], rls) - linked_set = {0} - for r in rls: - if r[0] in linked_set: - parent = r[0] - child = r[1] - else: - parent = r[1] - child = r[0] - - linked_set.add(child) - if not lst[parent].left: - lst[parent].left = lst[child] - else: - lst[parent].right = lst[child] - - return lst[0] - - def get_tree_sum(self, root): - """ - - :type root: TreeNode - """ - if not root.tree_sum: - left_sum = self.get_tree_sum(root.left) if root.left else 0 - right_sum = self.get_tree_sum(root.right) if root.right else 0 - root.tree_sum = left_sum+right_sum+root.item - - return root.tree_sum - - -# -# class GraphNode(object): -# def __init__(self, data): -# self.neighbors = [] -# self.data = -1 - -class Solution(object): - def __init__(self): - self.order = 0 - - def __inc_order(self): - self.order += 1 - return self.order - - def solve(self, cipher): - """ - https://github.com/pankajmore/DPP/blob/master/hackerrank/w2/cut-the-tree.cpp - - graph - dfs - use order count to present preserve the tree structure information - combination of graph and tree - :param cipher: the cipher - """ - N, data, rls = cipher - - # pure index representation without GraphNode strut - visited = [-1 for _ in xrange(N)] # visited order - E = [(0, 0) for _ in xrange(N-1)] - G = [[] for _ in xrange(N)] - v_sum = [-1 for _ in xrange(N)] # in tree order - _sum = sum(data) - - # construct graph - for ind, r in enumerate(rls): - u = r[0]-1 - v = r[1]-1 - - G[u].append(v) - G[v].append(u) - - E[ind] = (u, v) - - # dfs - # def dfs(s): - # visited[s] = self.__inc_order() - # v_sum[s] = data[s] - # for n in G[s]: - # if visited[n]==-1: # otherwise, already visited, which means parent. - # - # v_sum[s] += dfs(n) - # return v_sum[s] - - # lazy recursive dp - # problem: RuntimeError: maximum recursion depth exceeded - def get_sum(s): - if v_sum[s]==-1: - visited[s] = self.__inc_order() - v_sum[s] = data[s] - for n in G[s]: # dfs - if visited[n]==-1: - v_sum[s] += get_sum(n) - return v_sum[s] - - get_sum(0) - - mini = 1<<32 - for e in E: - u, v = e - if visited[u]>visited[v]: # if smaller, the node is in the middle of subtree - mini = min(mini, abs(_sum-get_sum(u)-get_sum(u))) - else: - mini = min(mini, abs(_sum-get_sum(v)-get_sum(v))) - return mini - - -if __name__=="__main__": - import sys - - sys.setrecursionlimit(100000) # otherwise not enough, stack problem with python - # print sys.getrecursionlimit() - f = open("1.in", "r") - # f = sys.stdin - N = int(f.readline().strip()) - nodes = map(int, f.readline().strip().split(' ')) - rls = [] - for t in xrange(N-1): - # construct rls - rls.append(map(int, f.readline().strip().split(' '))) - cipher = N, nodes, rls - s = "%s\n"%(Solution().solve(cipher)) - print s, \ No newline at end of file +# -*- coding: utf-8 -*- +""" +Atul is into graph theory, and he is learning about trees nowadays. He observed that the removal of an edge from a given +tree T will result in formation of two separate trees T1 and T2. + +Each vertex of the tree T is assigned a positive integer. Your task is to remove an edge, such that, the *Tree_diff* of +the resultant trees is minimized. *Tree_diff* is defined as + + F(T) = Sum of numbers written on each vertex of a Tree T + Tree_diff(T) = abs(F(T1) - F(T2)) +Input Format +The first line will contain an integer N, i.e., the number of vertices in the tree. +The next line will contain N integers separated by a single space, i.e., the values assigned to each of the vertices. +The next (N-1) lines contain pair of integers separated by a single space and denote the edges of the tree. +In the above input, the vertices are numbered from 1 to N. + +Output Format +A single line containing the minimum value of *Tree_diff*. + +Constraints +3 ≤ N ≤ 105 +1 ≤ number written on each vertex ≤ 1001 + +Sample Input + +6 +100 200 100 500 100 600 +1 2 +2 3 +2 5 +4 5 +5 6 +Sample Output + +400 +""" +__author__ = 'Danyang' + + +class TreeNode(object): + def __init__(self, item): + self.item = item + self.tree_sum = None + self.left = None + self.right = None + + def __repr__(self): + return repr(self.item) + + +class Solution_error(object): + def solve(self, cipher): + """ + it should be graph theory rather than tree + + bought test case #5 + :param cipher: the cipher + """ + root = self.construct_tree(cipher) + total = self.get_tree_sum(root) + mini = [1 << 32] # primitive is pass by value thus put it into array + self.dfs(root, total, mini) + return mini[0] + + def dfs(self, root, total, mini): + """ + pre-order + """ + if not root: + return + + mini[0] = min(mini[0], abs(total - root.tree_sum - root.tree_sum)) + self.dfs(root.left, total, mini) + self.dfs(root.right, total, mini) + + + def construct_tree(self, cipher): + """ + Hard part, the connection not necessarily from parent to child + errors may occur here due to the edge + """ + N, nodes, rls = cipher + lst = [TreeNode(val) for val in nodes] + # rls.sort(key=lambda x: x[1]) # secondary + # rls.sort(key=lambda x: x[0]) + rls = map(lambda x: [x[0] - 1, x[1] - 1], rls) + linked_set = {0} + for r in rls: + if r[0] in linked_set: + parent = r[0] + child = r[1] + else: + parent = r[1] + child = r[0] + + linked_set.add(child) + if not lst[parent].left: + lst[parent].left = lst[child] + else: + lst[parent].right = lst[child] + + return lst[0] + + def get_tree_sum(self, root): + """ + + :type root: TreeNode + """ + if not root.tree_sum: + left_sum = self.get_tree_sum(root.left) if root.left else 0 + right_sum = self.get_tree_sum(root.right) if root.right else 0 + root.tree_sum = left_sum + right_sum + root.item + + return root.tree_sum + + +# +# class GraphNode(object): +# def __init__(self, data): +# self.neighbors = [] +# self.data = -1 + +class Solution(object): + def __init__(self): + self.order = 0 + + def __inc_order(self): + self.order += 1 + return self.order + + def solve(self, cipher): + """ + https://github.com/pankajmore/DPP/blob/master/hackerrank/w2/cut-the-tree.cpp + + graph + dfs + use order count to present preserve the tree structure information + combination of graph and tree + :param cipher: the cipher + """ + N, data, rls = cipher + + # pure index representation without GraphNode strut + visited = [-1 for _ in xrange(N)] # visited order + E = [(0, 0) for _ in xrange(N - 1)] + G = [[] for _ in xrange(N)] + v_sum = [-1 for _ in xrange(N)] # in tree order + _sum = sum(data) + + # construct graph + for ind, r in enumerate(rls): + u = r[0] - 1 + v = r[1] - 1 + + G[u].append(v) + G[v].append(u) + + E[ind] = (u, v) + + # dfs + # def dfs(s): + # visited[s] = self.__inc_order() + # v_sum[s] = data[s] + # for n in G[s]: + # if visited[n]==-1: # otherwise, already visited, which means parent. + # + # v_sum[s] += dfs(n) + # return v_sum[s] + + # lazy recursive dp + # problem: RuntimeError: maximum recursion depth exceeded + def get_sum(s): + if v_sum[s] == -1: + visited[s] = self.__inc_order() + v_sum[s] = data[s] + for n in G[s]: # dfs + if visited[n] == -1: + v_sum[s] += get_sum(n) + return v_sum[s] + + get_sum(0) + + mini = 1 << 32 + for e in E: + u, v = e + if visited[u] > visited[v]: # if smaller, the node is in the middle of subtree + mini = min(mini, abs(_sum - get_sum(u) - get_sum(u))) + else: + mini = min(mini, abs(_sum - get_sum(v) - get_sum(v))) + return mini + + +if __name__ == "__main__": + import sys + + sys.setrecursionlimit(100000) # otherwise not enough, stack problem with python + # print sys.getrecursionlimit() + f = open("1.in", "r") + # f = sys.stdin + N = int(f.readline().strip()) + nodes = map(int, f.readline().strip().split(' ')) + rls = [] + for t in xrange(N - 1): + # construct rls + rls.append(map(int, f.readline().strip().split(' '))) + cipher = N, nodes, rls + s = "%s\n" % (Solution().solve(cipher)) + print s, diff --git a/Cutting boards.py b/Cutting boards.py index 4126d85..f7ce53a 100644 --- a/Cutting boards.py +++ b/Cutting boards.py @@ -1,86 +1,86 @@ -""" -lice gives a wooden board composed of M X N wooden square pieces to Bob and asks him to find the minimal cost of -breaking the board into square wooden pieces. Bob can cut the board along horizontal and vertical lines, and each cut -divides the board in smaller parts. Each cut has a cost depending on whether the cut is made along a horizontal or a -vertical line. - -Let us denote the costs of cutting it along consecutive vertical lines with x1, x2, ..., xn-1, and the cost of cutting -it along horizontal lines with y1, y2, ..., ym-1. If a cut (of cost c) is made and it passes through n segments, then -total cost of this cut will be n*c. - -The cost of cutting the whole board into single squares is the sum of the cost of successive cuts used to cut the whole -board into square wooden pieces of size 1x1. Bob should compute the minimal cost of breaking the whole wooden board into -squares of size 1x1. - -Bob needs your help to find the minimal cost. Can you help Bob with this challenge? - -Input Format -A single integer in the first line T, stating the number of test cases. T testcases follow. -For each test case, the first line contains two positive integers M and N separated by a single space. In the next line, -there are integers y1, y2, ..., ym-1, separated by spaces. Following them are integers x1, x2, ..., xn-1, separated by -spaces. -""" -MOD = 10**9+7 -__author__ = 'Danyang' - - -class Cost(object): - def __init__(self): - self.cost = 0 - - def __iadd__(self, other): - self.cost = (self.cost+other%MOD)%MOD - return self - - -class Solution(object): - def solve(self, cipher): - """ - Greedy approach - - Fixed #6 - #11 Wrong Answer due to Cost class - :param cipher: the cipher - """ - M, N, Y, X = cipher - - y = list(Y) - x = list(X) - - y.sort() - x.sort() - cost = Cost() - while x and y: - x_max = x[-1] - y_max = y[-1] - if x_max>y_max: - cost += x.pop()*(M-len(y)) - elif y_max>x_max: - cost += y.pop()*(N-len(x)) - else: - if sum(x)>sum(y): - cost += x.pop()*(M-len(y)) - else: - cost += y.pop()*(N-len(x)) - while x: - cost += x.pop()*(M-len(y)) - while y: - cost += y.pop()*(N-len(x)) - return cost.cost - - -if __name__=="__main__": - import sys - - f = open("1.in", "r") - # f = sys.stdin - testcases = int(f.readline().strip()) - - for t in xrange(testcases): - # construct cipher - M, N = map(int, f.readline().strip().split(" ")) - Y = map(int, f.readline().strip().split(" ")) - X = map(int, f.readline().strip().split(" ")) - cipher = [M, N, Y, X] - # solve - s = "%s\n"%(Solution().solve(cipher)) - print s, \ No newline at end of file +""" +lice gives a wooden board composed of M X N wooden square pieces to Bob and asks him to find the minimal cost of +breaking the board into square wooden pieces. Bob can cut the board along horizontal and vertical lines, and each cut +divides the board in smaller parts. Each cut has a cost depending on whether the cut is made along a horizontal or a +vertical line. + +Let us denote the costs of cutting it along consecutive vertical lines with x1, x2, ..., xn-1, and the cost of cutting +it along horizontal lines with y1, y2, ..., ym-1. If a cut (of cost c) is made and it passes through n segments, then +total cost of this cut will be n*c. + +The cost of cutting the whole board into single squares is the sum of the cost of successive cuts used to cut the whole +board into square wooden pieces of size 1x1. Bob should compute the minimal cost of breaking the whole wooden board into +squares of size 1x1. + +Bob needs your help to find the minimal cost. Can you help Bob with this challenge? + +Input Format +A single integer in the first line T, stating the number of test cases. T testcases follow. +For each test case, the first line contains two positive integers M and N separated by a single space. In the next line, +there are integers y1, y2, ..., ym-1, separated by spaces. Following them are integers x1, x2, ..., xn-1, separated by +spaces. +""" +MOD = 10 ** 9 + 7 +__author__ = 'Danyang' + + +class Cost(object): + def __init__(self): + self.cost = 0 + + def __iadd__(self, other): + self.cost = (self.cost + other % MOD) % MOD + return self + + +class Solution(object): + def solve(self, cipher): + """ + Greedy approach + + Fixed #6 - #11 Wrong Answer due to Cost class + :param cipher: the cipher + """ + M, N, Y, X = cipher + + y = list(Y) + x = list(X) + + y.sort() + x.sort() + cost = Cost() + while x and y: + x_max = x[-1] + y_max = y[-1] + if x_max > y_max: + cost += x.pop() * (M - len(y)) + elif y_max > x_max: + cost += y.pop() * (N - len(x)) + else: + if sum(x) > sum(y): + cost += x.pop() * (M - len(y)) + else: + cost += y.pop() * (N - len(x)) + while x: + cost += x.pop() * (M - len(y)) + while y: + cost += y.pop() * (N - len(x)) + return cost.cost + + +if __name__ == "__main__": + import sys + + f = open("1.in", "r") + # f = sys.stdin + testcases = int(f.readline().strip()) + + for t in xrange(testcases): + # construct cipher + M, N = map(int, f.readline().strip().split(" ")) + Y = map(int, f.readline().strip().split(" ")) + X = map(int, f.readline().strip().split(" ")) + cipher = [M, N, Y, X] + # solve + s = "%s\n" % (Solution().solve(cipher)) + print s, diff --git a/Cyclic Quadruples.py b/Cyclic Quadruples.py index 0f5a34d..7a06612 100644 --- a/Cyclic Quadruples.py +++ b/Cyclic Quadruples.py @@ -1,124 +1,124 @@ -# -*- coding: utf-8 -*- -""" -Problem Statement - -You need to count the number of quadruples of integers (X1, X2, X3, X4), such that Li ≤ Xi ≤ Ri for i = 1, 2, 3, 4 and -X1 ≠ X2, X2 ≠ X3, X3 ≠ X4, X4 ≠ X1. -""" -MOD = 10**9+7 -__author__ = 'Danyang' - - -class Solution_error(object): - def solve(self, cipher): - """ - ICP - - error - :param cipher: the cipher - """ - L = [cipher[2*i] for i in xrange(4)] - R = [cipher[2*i+1] for i in xrange(4)] - - result = 1 - for i in xrange(4): - result = (result*(R[i]-L[i]+1))%MOD - - pairs = [(0, 1), (0, 2), (0, 3), (1, 2), (1, 3), (2, 3)] - for pair in pairs: - other = max(0, min(R[i] for i in pair)-max(L[i] for i in pair)+1) - for i in xrange(4): - if i not in pair: - other = (other*(R[i]-L[i]+1))%MOD - result = (result-other)%MOD - - pairs = [(0, 1, 2), (0, 1, 3), (0, 2, 3), (1, 2, 3)] - for pair in pairs: - other = max(0, min(R[i] for i in pair)-max(L[i] for i in pair)+1) - for i in xrange(4): - if i not in pair: - other = (other*(R[i]-L[i]+1))%MOD - result = (result+other)%MOD - - result = (result-max(0, min(R)-max(L)+1))%MOD - return result - - -class Interval(object): - def __init__(self, l, r): - self.l = l - self.r = r - - def card(self): - if self.is_empty(): - return 0 - return self.r-self.l+1 - - def intersect(self, other): - if self.is_empty() or other.is_empty(): - return Interval(0, -1) - - l = max(self.l, other.l) - r = min(self.r, other.r) - return Interval(l, r) - - def is_empty(self): - return self.l>self.r - - -class Solution(object): - def solve(self, cipher): - """ - ICP - - https://sillymesillythoughtssillystuff.wordpress.com/tag/hackerrank/ - :param cipher: the cipher - """ - - R = [Interval(cipher[2*i], cipher[2*i+1]) for i in xrange(4)] - - w0 = 0 - w0 += R[0].card()*R[1].card()*R[2].card()*R[3].card() - w0 %= MOD - - w1 = 0 - for i in xrange(4): - w1 += R[i%4].intersect(R[(i+1)%4]).card()*R[(i+2)%4].card()*R[(i+3)%4].card() - w1 %= MOD - - w2 = 0 - for i in xrange(4): - w2 += R[i%4].intersect(R[(i+1)%4]).intersect(R[(i+2)%4]).card()*R[(i+3)%4].card() - w2 %= MOD - - for i in xrange(2): - w2 += R[i%4].intersect(R[(i+1)%4]).card()*R[(i+2)%4].intersect(R[(i+3)%4]).card() - w2 %= MOD - - w3 = 0 - for i in xrange(4): - w3 += R[i%4].intersect(R[(i+1)%4]).intersect(R[(i+2)%4]).intersect(R[(i+3)%4]).card() - w3 %= MOD - - w4 = 0 - w4 += R[0].intersect(R[1]).intersect(R[2]).intersect(R[3]).card() - w4 %= MOD - - return (w0-w1+w2-w3+w4)%MOD - - -if __name__=="__main__": - import sys - - f = open("1.in", "r") - # f = sys.stdin - solution = Solution() - testcases = int(f.readline().strip()) - - for t in xrange(testcases): - # construct cipher - cipher = map(int, f.readline().strip().split(' ')) - - # solve - s = "%s\n"%(solution.solve(cipher)) - print s, \ No newline at end of file +# -*- coding: utf-8 -*- +""" +Problem Statement + +You need to count the number of quadruples of integers (X1, X2, X3, X4), such that Li ≤ Xi ≤ Ri for i = 1, 2, 3, 4 and +X1 ≠ X2, X2 ≠ X3, X3 ≠ X4, X4 ≠ X1. +""" +MOD = 10 ** 9 + 7 +__author__ = 'Danyang' + + +class Solution_error(object): + def solve(self, cipher): + """ + ICP + + error + :param cipher: the cipher + """ + L = [cipher[2 * i] for i in xrange(4)] + R = [cipher[2 * i + 1] for i in xrange(4)] + + result = 1 + for i in xrange(4): + result = (result * (R[i] - L[i] + 1)) % MOD + + pairs = [(0, 1), (0, 2), (0, 3), (1, 2), (1, 3), (2, 3)] + for pair in pairs: + other = max(0, min(R[i] for i in pair) - max(L[i] for i in pair) + 1) + for i in xrange(4): + if i not in pair: + other = (other * (R[i] - L[i] + 1)) % MOD + result = (result - other) % MOD + + pairs = [(0, 1, 2), (0, 1, 3), (0, 2, 3), (1, 2, 3)] + for pair in pairs: + other = max(0, min(R[i] for i in pair) - max(L[i] for i in pair) + 1) + for i in xrange(4): + if i not in pair: + other = (other * (R[i] - L[i] + 1)) % MOD + result = (result + other) % MOD + + result = (result - max(0, min(R) - max(L) + 1)) % MOD + return result + + +class Interval(object): + def __init__(self, l, r): + self.l = l + self.r = r + + def card(self): + if self.is_empty(): + return 0 + return self.r - self.l + 1 + + def intersect(self, other): + if self.is_empty() or other.is_empty(): + return Interval(0, -1) + + l = max(self.l, other.l) + r = min(self.r, other.r) + return Interval(l, r) + + def is_empty(self): + return self.l > self.r + + +class Solution(object): + def solve(self, cipher): + """ + ICP + + https://sillymesillythoughtssillystuff.wordpress.com/tag/hackerrank/ + :param cipher: the cipher + """ + + R = [Interval(cipher[2 * i], cipher[2 * i + 1]) for i in xrange(4)] + + w0 = 0 + w0 += R[0].card() * R[1].card() * R[2].card() * R[3].card() + w0 %= MOD + + w1 = 0 + for i in xrange(4): + w1 += R[i % 4].intersect(R[(i + 1) % 4]).card() * R[(i + 2) % 4].card() * R[(i + 3) % 4].card() + w1 %= MOD + + w2 = 0 + for i in xrange(4): + w2 += R[i % 4].intersect(R[(i + 1) % 4]).intersect(R[(i + 2) % 4]).card() * R[(i + 3) % 4].card() + w2 %= MOD + + for i in xrange(2): + w2 += R[i % 4].intersect(R[(i + 1) % 4]).card() * R[(i + 2) % 4].intersect(R[(i + 3) % 4]).card() + w2 %= MOD + + w3 = 0 + for i in xrange(4): + w3 += R[i % 4].intersect(R[(i + 1) % 4]).intersect(R[(i + 2) % 4]).intersect(R[(i + 3) % 4]).card() + w3 %= MOD + + w4 = 0 + w4 += R[0].intersect(R[1]).intersect(R[2]).intersect(R[3]).card() + w4 %= MOD + + return (w0 - w1 + w2 - w3 + w4) % MOD + + +if __name__ == "__main__": + import sys + + f = open("1.in", "r") + # f = sys.stdin + solution = Solution() + testcases = int(f.readline().strip()) + + for t in xrange(testcases): + # construct cipher + cipher = map(int, f.readline().strip().split(' ')) + + # solve + s = "%s\n" % (solution.solve(cipher)) + print s, diff --git a/Dortmund Dilemma.py b/Dortmund Dilemma.py index e55b159..5a0ff36 100644 --- a/Dortmund Dilemma.py +++ b/Dortmund Dilemma.py @@ -1,96 +1,96 @@ -""" -Borussia Dortmund are a famous football (soccer) club from Germany. Apart from their fast-paced style of playing, the -thing that makes them unique is the hard to pronounce names of their players. - -The team's coach is your friend. He is in a dilemma as he can't decide how to make it easier to call the players by -name, during practice sessions. So, you advise him to assign easy names to his players. A name is easy to him if - -1. It consists of only one word. -2. It consists of only lowercase english letters. -3. It's length is exactly N. -4. It contains exactly K different letters from the 26 letters of English alphabet. -5. At least one of its proper prefixes matches with its proper suffix of same length. - -Given, N and K you have to tell him the number of easy names he can choose from modulo (109+9). - -Note : A prefix P of a name W is proper if, P!=W. Similarly, a suffix S of a name W is proper if, S!=W. - -Input Format -The first line of the input will contain T ( the number of testcases). Each of the next T lines will contain 2 space -separated integers N and K. -""" -__author__ = 'Danyang' -MOD = 10**9+9 - - -class Solution(object): - def __init__(self): - self.factorials = [0 for _ in xrange(26+1)] - self.factorials[0] = 1 - for i in xrange(1, 26+1): - self.factorials[i] = self.factorials[i-1]*i - - - # cached, rather than calculated eveytime - N = 10**5 - K = 26 - - self.F = [[0 for _ in xrange(K+1)] for _ in xrange(N+1)] - # starting from 1 - for j in xrange(1, K+1): - self.F[1][j] = j - for i in xrange(2, N+1): - if i&1==0: - self.F[i][j] = (self.F[i-1][j]*j-self.F[i/2][j]) - else: - self.F[i][j] = (self.F[i-1][j]*j) - self.F[i][j] %= MOD - - self.G = [[0 for _ in xrange(K+1)] for _ in xrange(N+1)] - - for j in xrange(1, K+1): - total = j - for i in xrange(1, N+1): - self.G[i][j] = total-self.F[i][j] # rather than using j**i - self.G[i][j] %= MOD - - total *= j - total %= MOD # otherwise time out - - - def solve(self, cipher): - """ - main solution function - :param cipher: the cipher - """ - N, K = cipher - - P = 0 - if K==1: - P += self.G[N][K] - else: - for j in xrange(K, 0, -1): - # P = self.G[N][K] - # P -= G[j] * (self.factorials[K]/(self.factorials[j]*self.factorials[K-j])) - # PIE: Principle of Inclusion-Exclusion - P += (-1)**(K-j)*self.G[N][j]*(self.factorials[K]/(self.factorials[j]*self.factorials[K-j])) - P %= MOD - - result = P*(self.factorials[26]/(self.factorials[K]*self.factorials[26-K])) - return result%MOD - - -if __name__=="__main__": - import sys - - f = open("1.in", "r") - # f = sys.stdin - testcases = int(f.readline().strip()) - solution = Solution() - for t in xrange(testcases): - # construct cipher - cipher = map(lambda x: int(x), f.readline().strip().split(' ')) - - # solve - s = "%s\n"%(solution.solve(cipher)) - print s, \ No newline at end of file +""" +Borussia Dortmund are a famous football (soccer) club from Germany. Apart from their fast-paced style of playing, the +thing that makes them unique is the hard to pronounce names of their players. + +The team's coach is your friend. He is in a dilemma as he can't decide how to make it easier to call the players by +name, during practice sessions. So, you advise him to assign easy names to his players. A name is easy to him if + +1. It consists of only one word. +2. It consists of only lowercase english letters. +3. It's length is exactly N. +4. It contains exactly K different letters from the 26 letters of English alphabet. +5. At least one of its proper prefixes matches with its proper suffix of same length. + +Given, N and K you have to tell him the number of easy names he can choose from modulo (109+9). + +Note : A prefix P of a name W is proper if, P!=W. Similarly, a suffix S of a name W is proper if, S!=W. + +Input Format +The first line of the input will contain T ( the number of testcases). Each of the next T lines will contain 2 space +separated integers N and K. +""" +__author__ = 'Danyang' +MOD = 10 ** 9 + 9 + + +class Solution(object): + def __init__(self): + self.factorials = [0 for _ in xrange(26 + 1)] + self.factorials[0] = 1 + for i in xrange(1, 26 + 1): + self.factorials[i] = self.factorials[i - 1] * i + + + # cached, rather than calculated eveytime + N = 10 ** 5 + K = 26 + + self.F = [[0 for _ in xrange(K + 1)] for _ in xrange(N + 1)] + # starting from 1 + for j in xrange(1, K + 1): + self.F[1][j] = j + for i in xrange(2, N + 1): + if i & 1 == 0: + self.F[i][j] = (self.F[i - 1][j] * j - self.F[i / 2][j]) + else: + self.F[i][j] = (self.F[i - 1][j] * j) + self.F[i][j] %= MOD + + self.G = [[0 for _ in xrange(K + 1)] for _ in xrange(N + 1)] + + for j in xrange(1, K + 1): + total = j + for i in xrange(1, N + 1): + self.G[i][j] = total - self.F[i][j] # rather than using j**i + self.G[i][j] %= MOD + + total *= j + total %= MOD # otherwise time out + + def solve(self, cipher): + """ + main solution function + :param cipher: the cipher + """ + N, K = cipher + + P = 0 + if K == 1: + P += self.G[N][K] + else: + for j in xrange(K, 0, -1): + # P = self.G[N][K] + # P -= G[j] * (self.factorials[K]/(self.factorials[j]*self.factorials[K-j])) + # PIE: Principle of Inclusion-Exclusion + P += (-1) ** (K - j) * self.G[N][j] * ( + self.factorials[K] / (self.factorials[j] * self.factorials[K - j])) + P %= MOD + + result = P * (self.factorials[26] / (self.factorials[K] * self.factorials[26 - K])) + return result % MOD + + +if __name__ == "__main__": + import sys + + f = open("1.in", "r") + # f = sys.stdin + testcases = int(f.readline().strip()) + solution = Solution() + for t in xrange(testcases): + # construct cipher + cipher = map(lambda x: int(x), f.readline().strip().split(' ')) + + # solve + s = "%s\n" % (solution.solve(cipher)) + print s, diff --git a/Dynamic Programming Classics - The Coin Change Problem.py b/Dynamic Programming Classics - The Coin Change Problem.py index ca1c7ae..d861499 100644 --- a/Dynamic Programming Classics - The Coin Change Problem.py +++ b/Dynamic Programming Classics - The Coin Change Problem.py @@ -1,52 +1,52 @@ -""" -Problem Statement - -How many different ways can you make change for an amount, given a list of coins? In this problem, your code will need -to efficiently compute the answer. -""" -__author__ = 'Danyang' - - -class Solution(object): - def __init__(self): - self.combs = {} - - def solve(self, cipher): - """ - Similar to Coinage with limited supply of coins - - :param cipher: the cipher - """ - C, N = cipher - return self.get_combinations(N, C, 0) - - # memoize - def get_combinations(self, t, lst, k): - if t==0: - return 1 - - if t<0 or k>=len(lst): - return 0 - - if (t, k) not in self.combs: - cnt = 0 - while t>=0: - cnt += self.get_combinations(t, lst, k+1) - t -= lst[k] - self.combs[(t, k)] = cnt - - return self.combs[(t, k)] - - -if __name__=="__main__": - import sys - - f = open("1.in", "r") - # f = sys.stdin - solution = Solution() - C = map(int, f.readline().strip().split(', ')) - N = int(f.readline().strip()) - cipher = C, N - # solve - s = "%s\n"%(solution.solve(cipher)) - print s, \ No newline at end of file +""" +Problem Statement + +How many different ways can you make change for an amount, given a list of coins? In this problem, your code will need +to efficiently compute the answer. +""" +__author__ = 'Danyang' + + +class Solution(object): + def __init__(self): + self.combs = {} + + def solve(self, cipher): + """ + Similar to Coinage with limited supply of coins + + :param cipher: the cipher + """ + C, N = cipher + return self.get_combinations(N, C, 0) + + # memoize + def get_combinations(self, t, lst, k): + if t == 0: + return 1 + + if t < 0 or k >= len(lst): + return 0 + + if (t, k) not in self.combs: + cnt = 0 + while t >= 0: + cnt += self.get_combinations(t, lst, k + 1) + t -= lst[k] + self.combs[(t, k)] = cnt + + return self.combs[(t, k)] + + +if __name__ == "__main__": + import sys + + f = open("1.in", "r") + # f = sys.stdin + solution = Solution() + C = map(int, f.readline().strip().split(', ')) + N = int(f.readline().strip()) + cipher = C, N + # solve + s = "%s\n" % (solution.solve(cipher)) + print s, diff --git a/Dynamic Programming Classics - The Longest Common Subsequence.py b/Dynamic Programming Classics - The Longest Common Subsequence.py index cfe0f3a..05d83f4 100644 --- a/Dynamic Programming Classics - The Longest Common Subsequence.py +++ b/Dynamic Programming Classics - The Longest Common Subsequence.py @@ -1,46 +1,46 @@ -""" -Problem Statement - -A subsequence is a sequence that can be derived from another sequence by deleting some elements without changing the -order of the remaining elements. Longest common subsequence (LCS) of 2 sequences is a subsequence, with maximal length, -which is common to both the sequences. -""" -__author__ = 'Danyang' - - -class Solution(object): - def solve(self, cipher): - """ - dp - f[i][j] = f[i-1][j-1]+1 - f[i][j] = max(f[i-1][j], f[i][j-1]) - :param cipher: the cipher - """ - m, n, A, B = cipher - f = [["" for _ in xrange(n+1)] for _ in xrange(m+1)] - for i in xrange(1, m+1): - for j in xrange(1, n+1): - if A[i-1]==B[j-1]: - # f[i][j] = f[i-1][j-1]+A[i-1] # otherwise cannot insert space - f[i][j] = f[i-1][j-1]+" "+A[i-1] - else: - if len(f[i-1][j])>len(f[i][j-1]): - f[i][j] = f[i-1][j] - else: - f[i][j] = f[i][j-1] - return f[m][n].strip() - - -if __name__=="__main__": - import sys - - f = open("1.in", "r") - # f = sys.stdin - solution = Solution() - m, n = map(int, f.readline().strip().split(' ')) - A = f.readline().strip().split(' ') - B = f.readline().strip().split(' ') - cipher = m, n, A, B - # solve - s = "%s\n"%(solution.solve(cipher)) - print s, \ No newline at end of file +""" +Problem Statement + +A subsequence is a sequence that can be derived from another sequence by deleting some elements without changing the +order of the remaining elements. Longest common subsequence (LCS) of 2 sequences is a subsequence, with maximal length, +which is common to both the sequences. +""" +__author__ = 'Danyang' + + +class Solution(object): + def solve(self, cipher): + """ + dp + f[i][j] = f[i-1][j-1]+1 + f[i][j] = max(f[i-1][j], f[i][j-1]) + :param cipher: the cipher + """ + m, n, A, B = cipher + f = [["" for _ in xrange(n + 1)] for _ in xrange(m + 1)] + for i in xrange(1, m + 1): + for j in xrange(1, n + 1): + if A[i - 1] == B[j - 1]: + # f[i][j] = f[i-1][j-1]+A[i-1] # otherwise cannot insert space + f[i][j] = f[i - 1][j - 1] + " " + A[i - 1] + else: + if len(f[i - 1][j]) > len(f[i][j - 1]): + f[i][j] = f[i - 1][j] + else: + f[i][j] = f[i][j - 1] + return f[m][n].strip() + + +if __name__ == "__main__": + import sys + + f = open("1.in", "r") + # f = sys.stdin + solution = Solution() + m, n = map(int, f.readline().strip().split(' ')) + A = f.readline().strip().split(' ') + B = f.readline().strip().split(' ') + cipher = m, n, A, B + # solve + s = "%s\n" % (solution.solve(cipher)) + print s, diff --git a/Dynamic Programming Classics - The Longest increasing subsequence.py b/Dynamic Programming Classics - The Longest increasing subsequence.py index 9a023d1..488ca8d 100644 --- a/Dynamic Programming Classics - The Longest increasing subsequence.py +++ b/Dynamic Programming Classics - The Longest increasing subsequence.py @@ -1,50 +1,50 @@ -""" -Problem Statement - -An Introduction to the Longest Increasing Subsequence Problems - -The task is to find the length of the longest subsequence in a given array of integers such that all elements of the -subsequence are sorted in ascending order. For example, the length of the LIS for { 15, 27, 14, 38, 26, 55, 46, 65, 85 } -is 6 and the longest increasing subsequence is {15, 27, 38, 55, 65, 85}. -""" -__author__ = 'Danyang' - - -class Solution(object): - def solve(self, cipher): - """ - LIS - - brute force is O(n^3) - reduced to O(n^2) - - let f[i] denote the LIS ended with A[i] - f[i] = max(f[j]+1 for jA[j]: - f[i] = max(f[i], f[j]+1) - maxa = max(maxa, f[i]) - return maxa - - -if __name__=="__main__": - import sys - - f = open("1.in", "r") - # f = sys.stdin - solution = Solution() - N = int(f.readline().strip()) - - A = [] - for _ in xrange(N): - A.append(int(f.readline().strip())) - cipher = N, A - # solve - s = "%s\n"%(solution.solve(cipher)) - print s, \ No newline at end of file +""" +Problem Statement + +An Introduction to the Longest Increasing Subsequence Problems + +The task is to find the length of the longest subsequence in a given array of integers such that all elements of the +subsequence are sorted in ascending order. For example, the length of the LIS for { 15, 27, 14, 38, 26, 55, 46, 65, 85 } +is 6 and the longest increasing subsequence is {15, 27, 38, 55, 65, 85}. +""" +__author__ = 'Danyang' + + +class Solution(object): + def solve(self, cipher): + """ + LIS + + brute force is O(n^3) + reduced to O(n^2) + + let f[i] denote the LIS ended with A[i] + f[i] = max(f[j]+1 for j A[j]: + f[i] = max(f[i], f[j] + 1) + maxa = max(maxa, f[i]) + return maxa + + +if __name__ == "__main__": + import sys + + f = open("1.in", "r") + # f = sys.stdin + solution = Solution() + N = int(f.readline().strip()) + + A = [] + for _ in xrange(N): + A.append(int(f.readline().strip())) + cipher = N, A + # solve + s = "%s\n" % (solution.solve(cipher)) + print s, diff --git a/Dynamic Programming Classics - The Maximum Subarray.py b/Dynamic Programming Classics - The Maximum Subarray.py index ee63b3f..62c88f4 100644 --- a/Dynamic Programming Classics - The Maximum Subarray.py +++ b/Dynamic Programming Classics - The Maximum Subarray.py @@ -1,50 +1,50 @@ -""" -Problem Statement - -Given an array of N elements, find the maximum possible sum of a (a) contiguous subarray (b) non-contiguous(not -necessarily contiguous) subarray. -""" -__author__ = 'Danyang' - - -class Solution(object): - def solve(self, cipher): - """ - main solution function - :param cipher: the cipher - """ - N, A = cipher - # SPECIAL CASE - maxa = max(A) - if maxa<0: - return "%d %d"%(maxa, maxa) - - sum_b = sum(filter(lambda x: x>0, A)) - - sum_a = 0 - current_sum = 0 - for a in A: - current_sum += a - if current_sum<0: - current_sum = 0 - sum_a = max(sum_a, current_sum) - - return "%d %d"%(sum_a, sum_b) - - -if __name__=="__main__": - import sys - - f = open("1.in", "r") - # f = sys.stdin - solution = Solution() - testcases = int(f.readline().strip()) - - for t in xrange(testcases): - # construct cipher - N = int(f.readline().strip()) - A = map(int, f.readline().strip().split(' ')) - cipher = N, A - # solve - s = "%s\n"%(solution.solve(cipher)) - print s, \ No newline at end of file +""" +Problem Statement + +Given an array of N elements, find the maximum possible sum of a (a) contiguous subarray (b) non-contiguous(not +necessarily contiguous) subarray. +""" +__author__ = 'Danyang' + + +class Solution(object): + def solve(self, cipher): + """ + main solution function + :param cipher: the cipher + """ + N, A = cipher + # SPECIAL CASE + maxa = max(A) + if maxa < 0: + return "%d %d" % (maxa, maxa) + + sum_b = sum(filter(lambda x: x > 0, A)) + + sum_a = 0 + current_sum = 0 + for a in A: + current_sum += a + if current_sum < 0: + current_sum = 0 + sum_a = max(sum_a, current_sum) + + return "%d %d" % (sum_a, sum_b) + + +if __name__ == "__main__": + import sys + + f = open("1.in", "r") + # f = sys.stdin + solution = Solution() + testcases = int(f.readline().strip()) + + for t in xrange(testcases): + # construct cipher + N = int(f.readline().strip()) + A = map(int, f.readline().strip().split(' ')) + cipher = N, A + # solve + s = "%s\n" % (solution.solve(cipher)) + print s, diff --git a/Encryption.py b/Encryption.py index 8177867..b2191db 100644 --- a/Encryption.py +++ b/Encryption.py @@ -1,81 +1,81 @@ -""" -https://www.hackerrank.com/challenges/encryption -One classic method for composing secret messages is called a square code. The spaces are removed from the english text -and the characters are written into a square (or rectangle). The width and height of the rectangle have the constraint, - -floor(sqrt( len(word) )) <= width, height <= ceil(sqrt( len(word) )) - -Among the possible squares, choose the one with the minimum area. - -In case of a rectangle, the number of rows will always be smaller than the number of columns. For example, the sentence -"if man was meant to stay on the ground god would have given us roots" is 54 characters long, so it is written in the -form of a rectangle with 7 rows and 8 columns. Many more rectangles can accomodate these characters; choose the one with -minimum area such that: length * width >= len(word) - - ifmanwas - meanttos - tayonthe - groundgo - dwouldha - vegivenu - sroots - -The coded message is obtained by reading the characters in a column, inserting a space, and then moving on to the next -column towards the right. For example, the message above is coded as: - -imtgdvs fearwer mayoogo anouuio ntnnlvt wttddes aohghn sseoau - -You will be given a message in English with no spaces between the words.The maximum message length can be 81 characters. -Print the encoded message. - -Here are some more examples: - -Sample Input: - -haveaniceday - -Sample Output: - -hae and via ecy -""" -from math import sqrt, floor, ceil - -__author__ = 'Danyang' - - -class Solution(object): - def solve(self, cipher): - l = len(cipher) - r = range(int(floor(sqrt(l))), int(ceil(sqrt(l)))+1) - - min_pair = (r[-1], r[-1]) - for h in r: - for w in r: - if h*w>=l and h*w= len(word) + + ifmanwas + meanttos + tayonthe + groundgo + dwouldha + vegivenu + sroots + +The coded message is obtained by reading the characters in a column, inserting a space, and then moving on to the next +column towards the right. For example, the message above is coded as: + +imtgdvs fearwer mayoogo anouuio ntnnlvt wttddes aohghn sseoau + +You will be given a message in English with no spaces between the words.The maximum message length can be 81 characters. +Print the encoded message. + +Here are some more examples: + +Sample Input: + +haveaniceday + +Sample Output: + +hae and via ecy +""" +from math import sqrt, floor, ceil + +__author__ = 'Danyang' + + +class Solution(object): + def solve(self, cipher): + l = len(cipher) + r = range(int(floor(sqrt(l))), int(ceil(sqrt(l))) + 1) + + min_pair = (r[-1], r[-1]) + for h in r: + for w in r: + if h * w >= l and h * w < min_pair[0] * min_pair[1]: + min_pair = (h, w) + h, w = min_pair + rect = [[None for _ in xrange(w)] for _ in xrange(h)] + for i in xrange(l): + rect[i / w][i % w] = cipher[i] + + result = [] + for j in xrange(w): + sb = [] + for i in xrange(h): + if rect[i][j] == None: break + sb.append(rect[i][j]) + result.append("".join(sb)) + + return " ".join(result) + + +if __name__ == "__main__": + import sys + + f = open("1.in", "r") + # f = sys.stdin + cipher = f.readline().strip() + + # solve + s = "%s\n" % (Solution().solve(cipher)) + print s, diff --git a/Even Tree.py b/Even Tree.py index df42264..f388297 100644 --- a/Even Tree.py +++ b/Even Tree.py @@ -1,71 +1,70 @@ -""" -Problem Statement - -You are given a tree (a simple connected graph with no cycles). You have to remove as many edges from the tree as -possible to obtain a forest with the condition that : Each connected component of the forest should contain an even -number of vertices. -""" -__author__ = 'Danyang' - - -class Solution(object): - def __init__(self, N, M): - self.f = [0 for _ in xrange(N+1)] # store the number of nodes of a subtree rooted at i - self.V = [[] for _ in xrange(N+1)] # 0 is dummy - self.E = [] - - def solve(self, cipher): - """ - count the number of subtree with even size - if a subtree is even, it can be detached from else and maintain the else's even odd Parity - - :param cipher: the cipher - """ - N, M, E = cipher - for e in E: - u, v = e - self.E.append([u, v]) - self.V[u].append(v) - self.V[v].append(u) - - self.get_sum(1, 0) - - result = 0 - for i in xrange(2, N+1): # excluding root - if self.f[i]%2==0: - result += 1 - return result - - - def get_sum(self, cur, pi): - """ - reduce graph to tree - dp (graph is mostly top-down dp) - dfs - """ - if self.f[cur]==0: - for nigh in self.V[cur]: - if nigh!=pi: - self.f[cur] += self.get_sum(nigh, cur) # child - - self.f[cur] += 1 # itself - - return self.f[cur] - - -if __name__=="__main__": - import sys - - f = open("1.in", "r") - # f = sys.stdin - N, M = map(int, f.readline().strip().split(' ')) - solution = Solution(N, M) - E = [] - for t in xrange(M): - # construct cipher - E.append(map(int, f.readline().strip().split(' '))) - - # solve - cipher = N, M, E - s = "%s\n"%(solution.solve(cipher)) - print s, \ No newline at end of file +""" +Problem Statement + +You are given a tree (a simple connected graph with no cycles). You have to remove as many edges from the tree as +possible to obtain a forest with the condition that : Each connected component of the forest should contain an even +number of vertices. +""" +__author__ = 'Danyang' + + +class Solution(object): + def __init__(self, N, M): + self.f = [0 for _ in xrange(N + 1)] # store the number of nodes of a subtree rooted at i + self.V = [[] for _ in xrange(N + 1)] # 0 is dummy + self.E = [] + + def solve(self, cipher): + """ + count the number of subtree with even size + if a subtree is even, it can be detached from else and maintain the else's even odd Parity + + :param cipher: the cipher + """ + N, M, E = cipher + for e in E: + u, v = e + self.E.append([u, v]) + self.V[u].append(v) + self.V[v].append(u) + + self.get_sum(1, 0) + + result = 0 + for i in xrange(2, N + 1): # excluding root + if self.f[i] % 2 == 0: + result += 1 + return result + + def get_sum(self, cur, pi): + """ + reduce graph to tree + dp (graph is mostly top-down dp) + dfs + """ + if self.f[cur] == 0: + for nigh in self.V[cur]: + if nigh != pi: + self.f[cur] += self.get_sum(nigh, cur) # child + + self.f[cur] += 1 # itself + + return self.f[cur] + + +if __name__ == "__main__": + import sys + + f = open("1.in", "r") + # f = sys.stdin + N, M = map(int, f.readline().strip().split(' ')) + solution = Solution(N, M) + E = [] + for t in xrange(M): + # construct cipher + E.append(map(int, f.readline().strip().split(' '))) + + # solve + cipher = N, M, E + s = "%s\n" % (solution.solve(cipher)) + print s, diff --git a/Fibonacci Modified.py b/Fibonacci Modified.py index 99d6e1a..40d04dd 100644 --- a/Fibonacci Modified.py +++ b/Fibonacci Modified.py @@ -1,40 +1,40 @@ -""" -Problem Statement - -A series is defined in the following manner: - -Given the nth and (n+1)th terms, the (n+2)th can be computed by the following relation -Tn+2 = (Tn+1)^2 + Tn -""" -__author__ = 'Danyang' - - -class Solution(object): - def solve(self, cipher): - """ - main solution function - :param cipher: the cipher - """ - A, B, N = cipher - - a, b = A, B - cnt = 1 - while cntA[i]: + idx = i - 1 + while idx != -1: + if A[idx] > A[i]: L[i] = idx break idx = L[idx] R = [-1 for _ in A] - for i in xrange(len(A)-2, -1, -1): - idx = i+1 - while idx!=-1: - if A[idx]>A[i]: + for i in xrange(len(A) - 2, -1, -1): + idx = i + 1 + while idx != -1: + if A[idx] > A[i]: R[i] = idx break idx = R[idx] maxa = -1 for i in xrange(len(A)): - left = L[i]+1 - right = R[i]+1 - maxa = max(maxa, left*right) + left = L[i] + 1 + right = R[i] + 1 + maxa = max(maxa, left * right) return maxa -if __name__=="__main__": +if __name__ == "__main__": import sys + f = open("0.in", "r") # f = sys.stdin solution = Solution() @@ -64,5 +65,5 @@ def solve(self, cipher): cipher = map(int, f.readline().strip().split(' ')) # solve - s = "%s\n"%(solution.solve(cipher)) - print s, \ No newline at end of file + s = "%s\n" % (solution.solve(cipher)) + print s, diff --git a/Find Median.py b/Find Median.py index d5dc638..17adb79 100644 --- a/Find Median.py +++ b/Find Median.py @@ -31,10 +31,10 @@ def insert(self, num): def balance(self): l1 = len(self.min_h) l2 = len(self.max_h) - if l1-l2 > 1: + if l1 - l2 > 1: heapq.heappush(self.max_h, -heapq.heappop(self.min_h)) self.balance() - elif l2-l1 > 1: + elif l2 - l1 > 1: heapq.heappush(self.min_h, -heapq.heappop(self.max_h)) self.balance() return @@ -42,15 +42,15 @@ def balance(self): def get_median(self): l1 = len(self.min_h) l2 = len(self.max_h) - m = (l1+l2-1)/2 - if (l1+l2) % 2 == 1: - if m == l2-1: + m = (l1 + l2 - 1) / 2 + if (l1 + l2) % 2 == 1: + if m == l2 - 1: return -self.max_h[0] elif m == l2: return self.min_h[0] raise Exception("not balanced") else: - return (-self.max_h[0]+self.min_h[0])/2.0 + return (-self.max_h[0] + self.min_h[0]) / 2.0 class Solution: @@ -66,8 +66,9 @@ def solve(self, cipher): return self.dh.get_median() -if __name__=="__main__": +if __name__ == "__main__": import sys + f = open("0.in", "r") # f = sys.stdin solution = Solution() @@ -77,4 +78,4 @@ def solve(self, cipher): # construct cipher cipher = int(f.readline().strip()) s = "%.1f\n" % (solution.solve(cipher)) - print s, \ No newline at end of file + print s, diff --git a/Find the Median.py b/Find the Median.py index 9499cf1..8009223 100644 --- a/Find the Median.py +++ b/Find the Median.py @@ -1,63 +1,63 @@ -""" -Problem Statement - -In the Quicksort challenges, you sorted an entire array. Sometimes, you just need specific information about a list of -numbers, and doing a full sort would be unnecessary. Can you figure out a way to use your partition code to find the -median in an array? -""" -__author__ = 'Danyang' - - -class Solution(object): - def solve(self, cipher): - """ - partial quick sort - :param cipher: the cipher - """ - N, A = cipher - if N%2==1: - return self.find_kth(A, 0, N-1, (N-1)/2) - else: - raise IndexError - - def find_kth(self, A, i, j, k): - """ - partial quick sort - """ - p = self.partition(A, i, j) - if p==k: - return A[p] - if p>k: - return self.find_kth(A, i, p-1, k) - else: - return self.find_kth(A, p+1, j, k) - - def partition(self, A, i, j): - if i>j: - raise IndexError - if i==j: - return i - - p = i - ptr_smaller = p - for ptr in xrange(p+1, j+1): # 1 for loop - if A[ptr] k: + return self.find_kth(A, i, p - 1, k) + else: + return self.find_kth(A, p + 1, j, k) + + def partition(self, A, i, j): + if i > j: + raise IndexError + if i == j: + return i + + p = i + ptr_smaller = p + for ptr in xrange(p + 1, j + 1): # 1 for loop + if A[ptr] < A[p]: + ptr_smaller += 1 + A[ptr], A[ptr_smaller] = A[ptr_smaller], A[ptr] + + A[p], A[ptr_smaller] = A[ptr_smaller], A[p] + return ptr_smaller + + +if __name__ == "__main__": + import sys + + f = open("1.in", "r") + # f = sys.stdin + solution = Solution() + N = int(f.readline().strip()) + A = map(int, f.readline().strip().split(' ')) + cipher = N, A + # solve + s = "%s\n" % (solution.solve(cipher)) + print s, diff --git a/Flip The Bits.py b/Flip The Bits.py index 9fb200b..2936191 100644 --- a/Flip The Bits.py +++ b/Flip The Bits.py @@ -18,15 +18,15 @@ def bitFlip(cipher): :type cipher: list :param cipher: the cipher """ - if len(cipher)<=2: + if len(cipher) <= 2: return len(cipher) - cipher = [val if val==1 else -1 for val in cipher] + cipher = [val if val == 1 else -1 for val in cipher] # diff = [cipher[i+1]-cipher[i] for i in xrange(len(cipher)-1)] maxl = 0 maxr = -1 - min_sum = 1<<31 + min_sum = 1 << 31 ssum = 0 l = 0 @@ -34,26 +34,26 @@ def bitFlip(cipher): for ind, val in enumerate(cipher): ssum += val - if ssum>0: - l = ind+1 + if ssum > 0: + l = ind + 1 r = ind ssum = 0 - if ssum<0: + if ssum < 0: r = ind - if min_sum>ssum: + if min_sum > ssum: min_sum = ssum maxr, maxl = r, l - cipher = [val if val==1 else 0 for val in cipher] - for i in xrange(maxl, maxr+1): + cipher = [val if val == 1 else 0 for val in cipher] + for i in xrange(maxl, maxr + 1): cipher[i] ^= 1 return sum(cipher) -if __name__=="__main__": +if __name__ == "__main__": import sys f = open("1.in", "r") @@ -66,5 +66,5 @@ def bitFlip(cipher): i = int(f.readline().strip()) cipher.append(i) # solve - s = "%s\n"%(bitFlip(cipher)) - print s, \ No newline at end of file + s = "%s\n" % (bitFlip(cipher)) + print s, diff --git a/Flowers.py b/Flowers.py index c7cecfc..0fee9c1 100644 --- a/Flowers.py +++ b/Flowers.py @@ -1,52 +1,52 @@ -""" -You and your K-1 friends want to buy N flowers. Flower number i has cost ci. Unfortunately the seller does not want just - one customer to buy a lot of flowers, so he tries to change the price of flowers for customers who have already bought - some flowers. More precisely, if a customer has already bought x flowers, he should pay (x+1)*ci dollars to buy flower - number i. -You and your K-1 friends want to buy all N flowers in such a way that you spend the least amount of money. You can buy -the flowers in any order. - -Input: - -The first line of input contains two integers N and K (K <= N). The next line contains N space separated positive -integers c1,c2,...,cN. - -Output: - -Print the minimum amount of money you (and your friends) have to pay in order to buy all N flowers. -""" -__author__ = 'Danyang' - - -class Solution(object): - def solve(self, cipher): - """ - Array math - - Sort the costs - Group the costs - :param cipher: the cipher - """ - N, K, C = cipher - - C.sort(reverse=True) - - group_cnt = N/K+1 # 1 is the last remaining group - total_cost = 0 - for i in xrange(group_cnt): - unit_cost = i+1 - total_cost += unit_cost*sum(C[i*K:(i+1)*K]) - return total_cost - - -if __name__=="__main__": - import sys - - f = open("1.in", "r") - # f = sys.stdin - N, K = map(int, f.readline().strip().split(' ')) - C = map(int, f.readline().strip().split(' ')) - cipher = N, K, C - # solve - s = "%s\n"%(Solution().solve(cipher)) - print s, \ No newline at end of file +""" +You and your K-1 friends want to buy N flowers. Flower number i has cost ci. Unfortunately the seller does not want just + one customer to buy a lot of flowers, so he tries to change the price of flowers for customers who have already bought + some flowers. More precisely, if a customer has already bought x flowers, he should pay (x+1)*ci dollars to buy flower + number i. +You and your K-1 friends want to buy all N flowers in such a way that you spend the least amount of money. You can buy +the flowers in any order. + +Input: + +The first line of input contains two integers N and K (K <= N). The next line contains N space separated positive +integers c1,c2,...,cN. + +Output: + +Print the minimum amount of money you (and your friends) have to pay in order to buy all N flowers. +""" +__author__ = 'Danyang' + + +class Solution(object): + def solve(self, cipher): + """ + Array math + + Sort the costs + Group the costs + :param cipher: the cipher + """ + N, K, C = cipher + + C.sort(reverse=True) + + group_cnt = N / K + 1 # 1 is the last remaining group + total_cost = 0 + for i in xrange(group_cnt): + unit_cost = i + 1 + total_cost += unit_cost * sum(C[i * K:(i + 1) * K]) + return total_cost + + +if __name__ == "__main__": + import sys + + f = open("1.in", "r") + # f = sys.stdin + N, K = map(int, f.readline().strip().split(' ')) + C = map(int, f.readline().strip().split(' ')) + cipher = N, K, C + # solve + s = "%s\n" % (Solution().solve(cipher)) + print s, diff --git a/Funny String.py b/Funny String.py index 81f228a..3d8e498 100644 --- a/Funny String.py +++ b/Funny String.py @@ -22,13 +22,14 @@ def solve(self, cipher): s = map(ord, list(s)) r = map(ord, list(r)) for i in xrange(1, len(s)): - if abs(s[i]-s[i-1])!=abs(r[i]-r[i-1]): + if abs(s[i] - s[i - 1]) != abs(r[i] - r[i - 1]): return "Not Funny" return "Funny" -if __name__=="__main__": +if __name__ == "__main__": import sys + f = open("0.in", "r") # f = sys.stdin solution = Solution() @@ -39,5 +40,5 @@ def solve(self, cipher): cipher = f.readline().strip() # solve - s = "%s\n"%(solution.solve(cipher)) - print s, \ No newline at end of file + s = "%s\n" % (solution.solve(cipher)) + print s, diff --git a/Game Of Rotation.py b/Game Of Rotation.py index 645c1eb..11a8a0f 100644 --- a/Game Of Rotation.py +++ b/Game Of Rotation.py @@ -1,60 +1,60 @@ -""" -Mark is an undergraduate student and he is interested in rotation. A conveyor belt competition is going on in the town -which Mark wants to win. In the competition, there's A conveyor belt which can be represented as a strip of 1xN blocks. -Each block has a number written on it. The belt keeps rotating in such a way that after each rotation, each block is -shifted to left of it and the first block goes to last position. - -There is a switch near the conveyer belt which can stop the belt. Each participant would be given a single chance to -stop the belt and his PMEAN would be calculated. - -PMEAN is calculated using the sequence which is there on the belt when it stops. The participant having highest PMEAN is -the winner. There can be multiple winners. - -Mark wants to be among the winners. What PMEAN he should try to get which guarantees him to be the winner. - -PMEAN=\sumi=1ni\timesa[i] -where a represents the configuration of conveyor belt when it is stopped. Indexing starts from 1. - -Input Format -First line contains N denoting the number of elements on the belt. -Second line contains N space separated integers. -""" -__author__ = 'Danyang' - - -class Solution(object): - def solve(self, cipher): - """ - Math - brute O(n^2) - math O(n)+O(n) - :param cipher: the cipher - """ - A = cipher - N = len(A) - _sum = sum(A) - _max = -1<<65 # 64-bit - - s = 0 - for ind, val in enumerate(A): - s += (ind+1)*val - - _max = max(_max, s) - for i in xrange(N): - s = s+_sum-N*A[N-1-i] - _max = max(_max, s) - - return _max - - -if __name__=="__main__": - import sys - - f = open("1.in", "r") - # f = sys.stdin - N = int(f.readline().strip()) - cipher = map(int, f.readline().strip().split(' ')) - - # solve - s = "%s\n"%(Solution().solve(cipher)) - print s, \ No newline at end of file +""" +Mark is an undergraduate student and he is interested in rotation. A conveyor belt competition is going on in the town +which Mark wants to win. In the competition, there's A conveyor belt which can be represented as a strip of 1xN blocks. +Each block has a number written on it. The belt keeps rotating in such a way that after each rotation, each block is +shifted to left of it and the first block goes to last position. + +There is a switch near the conveyer belt which can stop the belt. Each participant would be given a single chance to +stop the belt and his PMEAN would be calculated. + +PMEAN is calculated using the sequence which is there on the belt when it stops. The participant having highest PMEAN is +the winner. There can be multiple winners. + +Mark wants to be among the winners. What PMEAN he should try to get which guarantees him to be the winner. + +PMEAN=\sumi=1ni\timesa[i] +where a represents the configuration of conveyor belt when it is stopped. Indexing starts from 1. + +Input Format +First line contains N denoting the number of elements on the belt. +Second line contains N space separated integers. +""" +__author__ = 'Danyang' + + +class Solution(object): + def solve(self, cipher): + """ + Math + brute O(n^2) + math O(n)+O(n) + :param cipher: the cipher + """ + A = cipher + N = len(A) + _sum = sum(A) + _max = -1 << 65 # 64-bit + + s = 0 + for ind, val in enumerate(A): + s += (ind + 1) * val + + _max = max(_max, s) + for i in xrange(N): + s = s + _sum - N * A[N - 1 - i] + _max = max(_max, s) + + return _max + + +if __name__ == "__main__": + import sys + + f = open("1.in", "r") + # f = sys.stdin + N = int(f.readline().strip()) + cipher = map(int, f.readline().strip().split(' ')) + + # solve + s = "%s\n" % (Solution().solve(cipher)) + print s, diff --git a/Game of Thrones - I.py b/Game of Thrones - I.py index 7e7b605..239467a 100644 --- a/Game of Thrones - I.py +++ b/Game of Thrones - I.py @@ -19,20 +19,21 @@ def solve(self, cipher): cnt = 0 for v in d.values(): - if v&1==1: + if v & 1 == 1: cnt += 1 - if cnt>1: + if cnt > 1: return "NO" return "YES" -if __name__=="__main__": +if __name__ == "__main__": import sys + f = open("0.in", "r") # f = sys.stdin solution = Solution() cipher = f.readline().strip() # solve - s = "%s\n"%(solution.solve(cipher)) - print s, \ No newline at end of file + s = "%s\n" % (solution.solve(cipher)) + print s, diff --git a/Gem Stones.py b/Gem Stones.py index 6a58677..d0380a7 100644 --- a/Gem Stones.py +++ b/Gem Stones.py @@ -1,37 +1,37 @@ -""" -John has discovered various rocks. Each rock is composed of various elements, and each element is represented by a -lowercase latin letter from 'a' to 'z'. An element can be present multiple times in a rock. An element is called a -'gem-element' if it occurs at least once in each of the rocks. - -Given the list of N rocks with their compositions, display the number of gem-elements that exist in those rocks. - -Input Format -The first line consists of N, the number of rocks. -Each of the next N lines contain rocks' composition. Each composition consists of lowercase letters of English alphabet. -""" -__author__ = 'Danyang' - - -class Solution(object): - def solve(self, cipher): - """ - main solution function - :param cipher: the cipher - """ - return len(reduce(lambda x, y: x&y, [set(list(elt)) for elt in cipher])) - - -if __name__=="__main__": - import sys - - f = open("1.in", "r") - # f = sys.stdin - number = int(f.readline().strip()) - cipher = [] - for t in xrange(number): - # construct cipher - cipher.append(f.readline().strip()) - - # solve - s = "%s\n"%(Solution().solve(cipher)) - print s, \ No newline at end of file +""" +John has discovered various rocks. Each rock is composed of various elements, and each element is represented by a +lowercase latin letter from 'a' to 'z'. An element can be present multiple times in a rock. An element is called a +'gem-element' if it occurs at least once in each of the rocks. + +Given the list of N rocks with their compositions, display the number of gem-elements that exist in those rocks. + +Input Format +The first line consists of N, the number of rocks. +Each of the next N lines contain rocks' composition. Each composition consists of lowercase letters of English alphabet. +""" +__author__ = 'Danyang' + + +class Solution(object): + def solve(self, cipher): + """ + main solution function + :param cipher: the cipher + """ + return len(reduce(lambda x, y: x & y, [set(list(elt)) for elt in cipher])) + + +if __name__ == "__main__": + import sys + + f = open("1.in", "r") + # f = sys.stdin + number = int(f.readline().strip()) + cipher = [] + for t in xrange(number): + # construct cipher + cipher.append(f.readline().strip()) + + # solve + s = "%s\n" % (Solution().solve(cipher)) + print s, diff --git a/Grid Challenge.py b/Grid Challenge.py index 7151822..2b68bf2 100644 --- a/Grid Challenge.py +++ b/Grid Challenge.py @@ -30,14 +30,15 @@ def solve(self, cipher): cipher = map(lambda x: sorted(x), cipher) # print cipher for j in xrange(n): - for i in xrange(m-1): - if cipher[i][j]>cipher[i+1][j]: + for i in xrange(m - 1): + if cipher[i][j] > cipher[i + 1][j]: return "NO" return "YES" -if __name__=="__main__": +if __name__ == "__main__": import sys + f = open("1.in", "r") # f = sys.stdin solution = Solution() @@ -51,5 +52,5 @@ def solve(self, cipher): cipher.append(list(f.readline().strip())) # solve - s = "%s\n"%(solution.solve(cipher)) - print s, \ No newline at end of file + s = "%s\n" % (solution.solve(cipher)) + print s, diff --git a/Hexagonal Grid.py b/Hexagonal Grid.py index ba7f0a9..bae5ce1 100644 --- a/Hexagonal Grid.py +++ b/Hexagonal Grid.py @@ -31,13 +31,13 @@ def rec(self, grid): for i in xrange(m): for j in xrange(n): if not changed: # control the start from top, left - if grid[i][j]==0: + if grid[i][j] == 0: changed = True grid[i][j] = 1 for d in self.delta: - i2 = i+d[0] - j2 = j+d[1] - if 0<=i2 1 - -Input Format -The first line contains T, number of test cases. -T lines follows. Each line contains an integer N. -""" -__author__ = 'Danyang' -fib = lambda n: reduce(lambda x, n: [x[1], x[0]+x[1]], xrange(n), [0, 1])[0] - - -class Solution(object): - def solve(self, cipher): - """ - main solution function - :param cipher: the cipher - """ - num = int(cipher) - n = 0 - while fib(n) 1 + +Input Format +The first line contains T, number of test cases. +T lines follows. Each line contains an integer N. +""" +__author__ = 'Danyang' +fib = lambda n: reduce(lambda x, n: [x[1], x[0] + x[1]], xrange(n), [0, 1])[0] + + +class Solution(object): + def solve(self, cipher): + """ + main solution function + :param cipher: the cipher + """ + num = int(cipher) + n = 0 + while fib(n) < num: + n += 1 + if fib(n) == num: + return "IsFibo" + else: + return "IsNotFibo" + + +if __name__ == "__main__": + import sys + + f = open("1.in", "r") + # f = sys.stdin + testcases = int(f.readline().strip()) + + for t in xrange(testcases): + # construct cipher + cipher = f.readline().strip() + + # solve + s = "%s\n" % (Solution().solve(cipher)) + print s, diff --git a/Jim and the Orders.py b/Jim and the Orders.py index c64ea77..00dc1d9 100644 --- a/Jim and the Orders.py +++ b/Jim and the Orders.py @@ -36,12 +36,13 @@ def solve(self, cipher): """ A = cipher n = len(A) - idx = sorted(range(n), key=lambda k: A[k][0]+A[k][1]) - return " ".join(map(lambda x: str(x+1), idx)) + idx = sorted(range(n), key=lambda k: A[k][0] + A[k][1]) + return " ".join(map(lambda x: str(x + 1), idx)) -if __name__=="__main__": +if __name__ == "__main__": import sys + f = open("0.in", "r") # f = sys.stdin solution = Solution() @@ -54,5 +55,5 @@ def solve(self, cipher): cipher.append(tuple(t)) # solve - s = "%s\n"%(solution.solve(cipher)) - print s, \ No newline at end of file + s = "%s\n" % (solution.solve(cipher)) + print s, diff --git a/John and GCD list.py b/John and GCD list.py index 5f5cddb..6f908da 100644 --- a/John and GCD list.py +++ b/John and GCD list.py @@ -1,57 +1,57 @@ -# -*- coding: utf-8 -*- -""" -Problem Statement - -John is new to Mathematics and does not know how to calculate GCD of numbers. So he wants you to help him in a few GCD -calculations. John has a list A of numbers, indexed 1 to N. He wants to create another list B having N+1 numbers, -indexed from 1 to N+1, and having the following property: - -GCD(B[i], B[i+1]) = A[i], ∀ 1 ≤ i ≤ N - -As there can be many such lists, John wants to know the list B in which sum of all elements is minimum. It is guaranteed -that such a list will always exist. - -Input Format -The first line contains an integer T, i.e., the number of the test cases. T testcases follow. -The first line of each test case contains an integer N, i.e., the number of elements in the array. -The second line of each test case contains N space separated integers that denote the elements of the list A. -""" -__author__ = 'Danyang' - - -class Solution(object): - def solve(self, cipher): - """ - gcd and scf - :param cipher: the cipher - """ - A = cipher - B = [] - B.append(A[0]) - for i in xrange(1, len(A)): - B.append(A[i]*A[i-1]/self.gcd(A[i], A[i-1])) - B.append(A[-1]) - - return " ".join(map(str, B)) - - def gcd(self, a, b): - while b: - a, b = b, a%b - return a - - -if __name__=="__main__": - import sys - - f = open("1.in", "r") - # f = sys.stdin - testcases = int(f.readline().strip()) - - for t in xrange(testcases): - # construct cipher - N = int(f.readline().strip()) - cipher = map(int, f.readline().strip().split(' ')) - - # solve - s = "%s\n"%(Solution().solve(cipher)) - print s, \ No newline at end of file +# -*- coding: utf-8 -*- +""" +Problem Statement + +John is new to Mathematics and does not know how to calculate GCD of numbers. So he wants you to help him in a few GCD +calculations. John has a list A of numbers, indexed 1 to N. He wants to create another list B having N+1 numbers, +indexed from 1 to N+1, and having the following property: + +GCD(B[i], B[i+1]) = A[i], ∀ 1 ≤ i ≤ N + +As there can be many such lists, John wants to know the list B in which sum of all elements is minimum. It is guaranteed +that such a list will always exist. + +Input Format +The first line contains an integer T, i.e., the number of the test cases. T testcases follow. +The first line of each test case contains an integer N, i.e., the number of elements in the array. +The second line of each test case contains N space separated integers that denote the elements of the list A. +""" +__author__ = 'Danyang' + + +class Solution(object): + def solve(self, cipher): + """ + gcd and scf + :param cipher: the cipher + """ + A = cipher + B = [] + B.append(A[0]) + for i in xrange(1, len(A)): + B.append(A[i] * A[i - 1] / self.gcd(A[i], A[i - 1])) + B.append(A[-1]) + + return " ".join(map(str, B)) + + def gcd(self, a, b): + while b: + a, b = b, a % b + return a + + +if __name__ == "__main__": + import sys + + f = open("1.in", "r") + # f = sys.stdin + testcases = int(f.readline().strip()) + + for t in xrange(testcases): + # construct cipher + N = int(f.readline().strip()) + cipher = map(int, f.readline().strip().split(' ')) + + # solve + s = "%s\n" % (Solution().solve(cipher)) + print s, diff --git a/Journey to Mars.py b/Journey to Mars.py index 3cc30ee..dd9576c 100644 --- a/Journey to Mars.py +++ b/Journey to Mars.py @@ -1,63 +1,63 @@ -""" -Problem Statement - -Elon Musk has succesfully built an automated staircase from Earth to Mars. Many people want to go to Mars, but that's -not possible due to limited capacity of the staircase and logistics involved. Hence, Elon asks interested candidates to -solve a tough challenge. If they solve it, they get a chance to visit Mars, otherwise not. Sam is highly interested in -going to Mars. Can you help him solve the challenge? - -The staircase has N steps. It can either go step by step, or at each step, it can take a jump of at most N steps. - -Elon is interested to know the number of ways in which you can go to Mars. Since the number of steps in stairs can be -insanely large, Elon is only interested in the first and the last K digits of number of ways from which he can compute -the actual answer with his algorithm. -""" -import math -from decimal import * - -__author__ = 'Danyang' - - -class Solution(object): - def __init__(self): - getcontext().prec = 28 - - def solve(self, cipher): - """ - first K digit of B^N - http://discuss.codechef.com/questions/15398/first-k-digits-of-nn - - :param cipher: the cipher - """ - N, K = cipher - LSB = pow(2, N-1, 10**K) - - # calculate MSB - MSB = int(str(self.get_MSB(2, N-1)*10**K)[:K]) - - return MSB+LSB - - def get_MSB(self, b, n): - """ - Use Decimal() otherwise only works for small numbers - """ - p = Decimal(n)*Decimal(b).log10() - f = Decimal(p)-Decimal(math.floor(p)) - return Decimal(10)**f - - -if __name__=="__main__": - import sys - - f = open("1.in", "r") - # f = sys.stdin - solution = Solution() - testcases = int(f.readline().strip()) - - for t in xrange(testcases): - # construct cipher - cipher = map(int, f.readline().strip().split(' ')) - - # solve - s = "%s\n"%(solution.solve(cipher)) - print s, \ No newline at end of file +""" +Problem Statement + +Elon Musk has succesfully built an automated staircase from Earth to Mars. Many people want to go to Mars, but that's +not possible due to limited capacity of the staircase and logistics involved. Hence, Elon asks interested candidates to +solve a tough challenge. If they solve it, they get a chance to visit Mars, otherwise not. Sam is highly interested in +going to Mars. Can you help him solve the challenge? + +The staircase has N steps. It can either go step by step, or at each step, it can take a jump of at most N steps. + +Elon is interested to know the number of ways in which you can go to Mars. Since the number of steps in stairs can be +insanely large, Elon is only interested in the first and the last K digits of number of ways from which he can compute +the actual answer with his algorithm. +""" +import math +from decimal import * + +__author__ = 'Danyang' + + +class Solution(object): + def __init__(self): + getcontext().prec = 28 + + def solve(self, cipher): + """ + first K digit of B^N + http://discuss.codechef.com/questions/15398/first-k-digits-of-nn + + :param cipher: the cipher + """ + N, K = cipher + LSB = pow(2, N - 1, 10 ** K) + + # calculate MSB + MSB = int(str(self.get_MSB(2, N - 1) * 10 ** K)[:K]) + + return MSB + LSB + + def get_MSB(self, b, n): + """ + Use Decimal() otherwise only works for small numbers + """ + p = Decimal(n) * Decimal(b).log10() + f = Decimal(p) - Decimal(math.floor(p)) + return Decimal(10) ** f + + +if __name__ == "__main__": + import sys + + f = open("1.in", "r") + # f = sys.stdin + solution = Solution() + testcases = int(f.readline().strip()) + + for t in xrange(testcases): + # construct cipher + cipher = map(int, f.readline().strip().split(' ')) + + # solve + s = "%s\n" % (solution.solve(cipher)) + print s, diff --git a/K Candy Store.py b/K Candy Store.py index ec9a56b..d260159 100644 --- a/K Candy Store.py +++ b/K Candy Store.py @@ -1,49 +1,49 @@ -""" -Problem Statement - -Jim enters a candy shop which has N different types of candies, each candy is of the same price. Jim has enough money to -buy K candies. In how many different ways can he purchase K candies if there are infinite candies of each kind? -""" -MOD = 10**9 -__author__ = 'Danyang' - - -class Solution(object): - def __init__(self): - """ - \binom nk=\binom{n-1}{k-1}+\binom{n-1}k, \text{ for } 0=0: - f[i][c] = max(f[i-1][c], f[i-1][c-A[i-1]]+A[i-1], f[i][c-A[i-1]]+A[i-1]) + f = [[0 for _ in xrange(k + 1)] for _ in xrange(n + 1)] # f[0, :] is dummies + for i in xrange(n + 1): + for c in xrange(k + 1): + f[i][c] = f[i - 1][c] + temp = c - A[i - 1] + if temp >= 0: + f[i][c] = max(f[i - 1][c], f[i - 1][c - A[i - 1]] + A[i - 1], f[i][c - A[i - 1]] + A[i - 1]) return f[n][k] -if __name__=="__main__": +if __name__ == "__main__": import sys + f = open("0.in", "r") # f = sys.stdin solution = Solution() @@ -59,5 +60,5 @@ def solve(self, cipher): cipher = n, k, A # solve - s = "%s\n"%(solution.solve(cipher)) - print s, \ No newline at end of file + s = "%s\n" % (solution.solve(cipher)) + print s, diff --git a/Largest Permutation.py b/Largest Permutation.py index b0f8a3b..86ee8c1 100644 --- a/Largest Permutation.py +++ b/Largest Permutation.py @@ -23,29 +23,30 @@ def solve(self, cipher): """ N, K, lst = cipher for i in xrange(len(lst)): - if K<=0: + if K <= 0: break maxa, idx = -1, 0 for j in xrange(i, len(lst)): - if lst[j]>maxa: + if lst[j] > maxa: maxa = lst[j] idx = j - if idx!=i: + if idx != i: K -= 1 lst[idx], lst[i] = lst[i], lst[idx] return " ".join(map(str, lst)) -if __name__=="__main__": +if __name__ == "__main__": import sys + f = open("1.in", "r") # f = sys.stdin solution = Solution() - N, K = map(int, f.readline().strip().split(' ')) + N, K = map(int, f.readline().strip().split(' ')) lst = map(int, f.readline().strip().split(' ')) cipher = (N, K, lst) # solve - s = "%s\n"%(solution.solve(cipher)) - print s, \ No newline at end of file + s = "%s\n" % (solution.solve(cipher)) + print s, diff --git a/Lego Blocks.py b/Lego Blocks.py index 662da88..e290950 100644 --- a/Lego Blocks.py +++ b/Lego Blocks.py @@ -39,23 +39,23 @@ def solve(self, cipher): :return: """ N, M = cipher - f = [0 for _ in xrange(M+1)] - s = [0 for _ in xrange(M+1)] + f = [0 for _ in xrange(M + 1)] + s = [0 for _ in xrange(M + 1)] f[0] = 1 - for j in xrange(1, M+1): + for j in xrange(1, M + 1): for l in self.lens: - if j-l>=0: - f[j] += f[j-l] + if j - l >= 0: + f[j] += f[j - l] f[j] %= MOD f_N = map(lambda x: pow(x, N, MOD), f) - for j in xrange(1, M+1): + for j in xrange(1, M + 1): s[j] = f_N[j] - if s[j]<=0: break + if s[j] <= 0: break for k in xrange(1, j): # sum - s[j] -= f_N[j-k]*s[k] + s[j] -= f_N[j - k] * s[k] s[j] %= MOD return s[M] @@ -77,27 +77,27 @@ def solve(self, cipher): :return: """ N, M = cipher - f = [[0 for _ in xrange(M+1)] for _ in xrange(N+1)] - s = [[0 for _ in xrange(M+1)] for _ in xrange(N+1)] + f = [[0 for _ in xrange(M + 1)] for _ in xrange(N + 1)] + s = [[0 for _ in xrange(M + 1)] for _ in xrange(N + 1)] f[1][0] = 1 - for j in xrange(1, M+1): + for j in xrange(1, M + 1): for l in self.lens: - if j-l>=0: - f[1][j] += f[1][j-l] + if j - l >= 0: + f[1][j] += f[1][j - l] f[1][j] %= MOD - for i in xrange(2, N+1): - for j in xrange(1, M+1): - f[i][j] = f[i-1][j]*f[1][j] + for i in xrange(2, N + 1): + for j in xrange(1, M + 1): + f[i][j] = f[i - 1][j] * f[1][j] f[i][j] %= MOD - for i in xrange(1, N+1): - for j in xrange(1, M+1): + for i in xrange(1, N + 1): + for j in xrange(1, M + 1): s[i][j] = f[i][j] - if s[i][j]<=0: break + if s[i][j] <= 0: break for k in xrange(1, j): # sum - s[i][j] -= f[i][j-k]*s[i][k] + s[i][j] -= f[i][j - k] * s[i][k] s[i][j] %= MOD return s[N][M] @@ -111,27 +111,28 @@ def solve_error(self, cipher): :param cipher: the cipher """ N, M = cipher - f = [[0 for _ in xrange(M+1)] for _ in xrange(N+1)] + f = [[0 for _ in xrange(M + 1)] for _ in xrange(N + 1)] f[1][1] = 1 - for j in xrange(1, M+1): + for j in xrange(1, M + 1): for l in self.lens: - if j-l>=1: - f[1][j] += f[1][j-l] - for j in xrange(1, M+1): - f[1][j] -= f[1][j-1] + if j - l >= 1: + f[1][j] += f[1][j - l] + for j in xrange(1, M + 1): + f[1][j] -= f[1][j - 1] - for i in xrange(2, N+1): - for j in xrange(1, M+1): + for i in xrange(2, N + 1): + for j in xrange(1, M + 1): cmb = i - for l in xrange(1, i+1): - f[i][j] += cmb*f[i-l][j-1]*(f[1][j]**i) # equivalent - cmb = cmb*(i-l)/(l+1) + for l in xrange(1, i + 1): + f[i][j] += cmb * f[i - l][j - 1] * (f[1][j] ** i) # equivalent + cmb = cmb * (i - l) / (l + 1) return f[N][M] -if __name__=="__main__": +if __name__ == "__main__": import sys + f = open("0.in", "r") # f = sys.stdin solution = Solution() @@ -142,5 +143,5 @@ def solve_error(self, cipher): cipher = map(int, f.readline().strip().split(' ')) # solve - s = "%s\n"%(solution.solve(cipher)) - print s, \ No newline at end of file + s = "%s\n" % (solution.solve(cipher)) + print s, diff --git a/Little Ashish's Huge Donation.py b/Little Ashish's Huge Donation.py index 9d2729a..9c80da6 100644 --- a/Little Ashish's Huge Donation.py +++ b/Little Ashish's Huge Donation.py @@ -1,60 +1,60 @@ -# -*- coding: utf-8 -*- -""" -Problem Statement - -Little Ashish is doing internship at multiple places. Instead of giving parties to his friends he decided to donate -candies to children. He likes solving puzzles and playing games. Hence he plays a small game. Suppose there are N -children. The rules of the game are: - -The ith child gets i2 candies (1≤i≤N). - -The yth child cannot get a candy until and unless all the children before him (1≤i=cipher: - break - else: - m2 = m - while m2!=0 and m2%5==0: - cnt += 1 - m2 /= 5 - m += 5 - - m -= 5 - return m - - def solve_math(self, cipher): - """ - fastest - """ - n = cipher - m = 0 - for i, p in self.M: - if p<=n: - cnt = n/p - n -= cnt*p - m += cnt*5**i - return m - - def solve(self, n): - """ - binary search - """ - l = 0 - h = 5*n - while l<=h: - mid = (l+h)/2 - cnt = self.prime_count(5, mid) - if cnt= cipher: + break + else: + m2 = m + while m2 != 0 and m2 % 5 == 0: + cnt += 1 + m2 /= 5 + m += 5 + + m -= 5 + return m + + def solve_math(self, cipher): + """ + fastest + """ + n = cipher + m = 0 + for i, p in self.M: + if p <= n: + cnt = n / p + n -= cnt * p + m += cnt * 5 ** i + return m + + def solve(self, n): + """ + binary search + """ + l = 0 + h = 5 * n + while l <= h: + mid = (l + h) / 2 + cnt = self.prime_count(5, mid) + if cnt < n: + l = mid + 1 + else: + h = mid - 1 + return l + + def prime_count(self, p, n): + """ + count number of p in n!'s factors, where p is a prime number + + complexity O(lg n) + """ + if n < p: + return 0 + + return n / p + self.prime_count(p, n / p) + + +if __name__ == "__main__": + import sys + + f = open("1.in", "r") + # f = sys.stdin + testcases = int(f.readline().strip()) + solution = Solution() + for t in xrange(testcases): + # construct cipher + cipher = int(f.readline().strip()) + + # solve + s = "%s\n" % (solution.solve(cipher)) + print s, diff --git a/Manasa loves Maths.py b/Manasa loves Maths.py index d7b4d24..49b2751 100644 --- a/Manasa loves Maths.py +++ b/Manasa loves Maths.py @@ -1,66 +1,66 @@ -# -*- coding: utf-8 -*- -""" -Problem Statement - -You are given an integer N. Is there a permutation of digits of integer that's divisible by 8? A permutation of digits -of integer N is defined as an integer formed by rearranging the digits of N. For example, if the number N = 123, then -{123, 132, 213, 231, 312, 321} are the possible permutations. - -Input Format -The first line contains an integer T i.e. number of test cases. -T lines follow, each containing the integer N. -""" -__author__ = 'Danyang' - - -class Solution(object): - def solve(self, cipher): - """ - starting from divided by 2, 4, then 8 - :param cipher: the cipher - """ - l = len(cipher) - if l==1: - if int(cipher)%8==0: - return "YES" - else: - return "NO" - elif l==2: - if int(cipher)%8==0 or int(cipher[::-1])%8==0: - return "YES" - else: - return "NO" - - # when there are 3 or more digits - hm = [0 for _ in xrange(10)] - for char in cipher: - hm[int(char)] += 1 - - for i in xrange(0, 1000, 8): - copy = list(hm) - s = "00"+str(i) - j = -1 - while j>=-3: # check 3 digits - d = int(s[j]) - if copy[d]<=0: break - copy[d] -= 1 - j -= 1 - if j==-4: - return "YES" - return "NO" - - -if __name__=="__main__": - import sys - - f = open("1.in", "r") - # f = sys.stdin - testcases = int(f.readline().strip()) - - for t in xrange(testcases): - # construct cipher - cipher = f.readline().strip() - - # solve - s = "%s\n"%(Solution().solve(cipher)) - print s, \ No newline at end of file +# -*- coding: utf-8 -*- +""" +Problem Statement + +You are given an integer N. Is there a permutation of digits of integer that's divisible by 8? A permutation of digits +of integer N is defined as an integer formed by rearranging the digits of N. For example, if the number N = 123, then +{123, 132, 213, 231, 312, 321} are the possible permutations. + +Input Format +The first line contains an integer T i.e. number of test cases. +T lines follow, each containing the integer N. +""" +__author__ = 'Danyang' + + +class Solution(object): + def solve(self, cipher): + """ + starting from divided by 2, 4, then 8 + :param cipher: the cipher + """ + l = len(cipher) + if l == 1: + if int(cipher) % 8 == 0: + return "YES" + else: + return "NO" + elif l == 2: + if int(cipher) % 8 == 0 or int(cipher[::-1]) % 8 == 0: + return "YES" + else: + return "NO" + + # when there are 3 or more digits + hm = [0 for _ in xrange(10)] + for char in cipher: + hm[int(char)] += 1 + + for i in xrange(0, 1000, 8): + copy = list(hm) + s = "00" + str(i) + j = -1 + while j >= -3: # check 3 digits + d = int(s[j]) + if copy[d] <= 0: break + copy[d] -= 1 + j -= 1 + if j == -4: + return "YES" + return "NO" + + +if __name__ == "__main__": + import sys + + f = open("1.in", "r") + # f = sys.stdin + testcases = int(f.readline().strip()) + + for t in xrange(testcases): + # construct cipher + cipher = f.readline().strip() + + # solve + s = "%s\n" % (Solution().solve(cipher)) + print s, diff --git a/Mark and Toys.py b/Mark and Toys.py index 92e05b8..d7d0c65 100644 --- a/Mark and Toys.py +++ b/Mark and Toys.py @@ -54,5 +54,5 @@ def solve(self, cipher): cipher = n, K, A # solve - s = "%s\n"%(solution.solve(cipher)) - print s, \ No newline at end of file + s = "%s\n" % (solution.solve(cipher)) + print s, diff --git a/Maximizing XOR.py b/Maximizing XOR.py index d943354..cb424eb 100644 --- a/Maximizing XOR.py +++ b/Maximizing XOR.py @@ -1,42 +1,42 @@ -""" -iven two integers: L and R, - -find the maximal values of A xor B given, L <= A <= B <= R - -Input Format -The input contains two lines, L is present in the first line. -R in the second line. - -Constraints -1 <= L <= R <= 103 - -Output Format -The maximal value as mentioned in the problem statement. -""" -__author__ = 'Danyang' - - -class Solution(object): - def solve(self, cipher): - """ - main solution function - :param cipher: the cipher - """ - global_max = -1 - A, B = cipher - for i in xrange(A, B+1): - for j in xrange(i+1, B+1): - global_max = max(global_max, i^j) - return global_max - - -if __name__=="__main__": - import sys - # f = open("1.in", "r") - f = sys.stdin - A = int(f.readline().strip()) - B = int(f.readline().strip()) - cipher = (A, B) - - s = "%s\n"%(Solution().solve(cipher)) - print s, \ No newline at end of file +""" +iven two integers: L and R, + +find the maximal values of A xor B given, L <= A <= B <= R + +Input Format +The input contains two lines, L is present in the first line. +R in the second line. + +Constraints +1 <= L <= R <= 103 + +Output Format +The maximal value as mentioned in the problem statement. +""" +__author__ = 'Danyang' + + +class Solution(object): + def solve(self, cipher): + """ + main solution function + :param cipher: the cipher + """ + global_max = -1 + A, B = cipher + for i in xrange(A, B + 1): + for j in xrange(i + 1, B + 1): + global_max = max(global_max, i ^ j) + return global_max + + +if __name__ == "__main__": + import sys + # f = open("1.in", "r") + f = sys.stdin + A = int(f.readline().strip()) + B = int(f.readline().strip()) + cipher = (A, B) + + s = "%s\n" % (Solution().solve(cipher)) + print s, diff --git a/Median.py b/Median.py index 2c3eef1..9c905ab 100644 --- a/Median.py +++ b/Median.py @@ -1,163 +1,163 @@ -""" -The median of M numbers is defined as the middle number after sorting them in order, if M is odd. Or it is the average -of the middle 2 numbers (again after sorting), if M is even. You have an empty number list at first. Then you can add in - or remove some number from the list. For each add or remove operation, output the median of numbers in the list. - -Example : -For a set of M = 5 numbers {9, 2, 8, 4, 1} the median is the third number in sorted set {1, 2, 4, 8, 9} which is 4. -Similarly, for a set of M = 4, {5, 2, 10, 4}, the median is the average of second and the third element in the sorted -set {2, 4, 5, 10} which is (4+5)/2 = 4.5. - -Input: -The first line is an integer N that indicates the number of operations. Each of the next N lines is either a x or r x . -a x indicates that x is added to the set, and r x indicates that x is removed from the set. -""" -__author__ = 'Danyang' -# from Queue import PriorityQueue # PriorityQueue does not support removal -import heapq - - -class Solution_TLE(object): - def __init__(self): - self.heap = [] - - def solve(self, cipher): - """ - Heap - - :param cipher: the cipher - """ - op = cipher[0] - num = int(cipher[1]) - if op=="r": - try: - self.heap.remove(num) - except ValueError: - return "Wrong!" - heapq.heapify(self.heap) - else: - heapq.heappush(self.heap, num) - - length = len(self.heap) - if not self.heap: - return "Wrong!" - pq = list(self.heap) - pq = [heapq.heappop(pq) for _ in xrange(length)] - if length&1==0: - return 0.5*(pq[length/2-1]+pq[length/2]) - else: - return pq[length/2] - - -class Solution_TLE2(object): - def __init__(self): - self.min_heap = [] - self.max_heap = [] # no max heap in Python - - def solve(self, cipher): - """ - Median_Heap - - Still TLE - Notice that 6, 7, 8 test cases time out - - :param cipher: the cipher - """ - op = cipher[0] - num = int(cipher[1]) - if op=="r": - try: - # if self.max_heap and -num>self.max_heap[0]: - if self.min_heap and num>=self.min_heap[0]: - self.min_heap.remove(num) - heapq.heapify(self.min_heap) - else: - self.max_heap.remove(-num) - heapq.heapify(self.max_heap) - if not self.min_heap and not self.max_heap: - return "Wrong!" - self.__balance() - except ValueError: - return "Wrong!" - else: - # if self.max_heap and -num>self.max_heap[0]: - if self.min_heap and num>=self.min_heap[0]: - heapq.heappush(self.min_heap, num) - else: - heapq.heappush(self.max_heap, -num) - self.__balance() - - # return "%g"%self.__get_median() # %g rather than %s to avoid trailing zero # general format # fail - output = str(self.__get_median()) - if output[-2:]==".0": - output = output[:-2] - return output - - def __balance(self): - if len(self.min_heap)>len(self.max_heap)+1: - item = heapq.heappop(self.min_heap) - heapq.heappush(self.max_heap, -item) - return - if len(self.max_heap)>len(self.min_heap)+1: - item = heapq.heappop(self.max_heap) - heapq.heappush(self.min_heap, -item) - return - - def __get_median(self): - if len(self.min_heap)==len(self.max_heap): - return 0.5*(self.min_heap[0]+(-1)*self.max_heap[0]) - elif len(self.min_heap)>len(self.max_heap): - return self.min_heap[0] - else: - return -self.max_heap[0] - - -from bisect import bisect_left - - -class Solution(object): - def __init__(self): - self.A = [] - - def solve(self, cipher): - """ - bisect - """ - op = cipher[0] - val = int(cipher[1]) - - pos = bisect_left(self.A, val) - if op=="r": - if pos>=len(self.A) or self.A[pos]!=val: - return "Wrong!" - else: - del (self.A[pos]) - else: # "a" - self.A.insert(pos, val) - - l = len(self.A) - if l==0: - return "Wrong!" - elif l&1==1: - return self.A[l/2] - else: - output = str(0.5*(self.A[l/2-1]+self.A[l/2])) - if output[-2:]==".0": - output = output[:-2] - return output - - -if __name__=="__main__": - import sys - - f = open("0.in", "r") - # f = sys.stdin - testcases = int(f.readline().strip()) - solution = Solution() - for t in xrange(testcases): - # construct cipher - cipher = f.readline().strip().split(' ') - - # solve - s = "%s\n"%(solution.solve(cipher)) - print s, \ No newline at end of file +""" +The median of M numbers is defined as the middle number after sorting them in order, if M is odd. Or it is the average +of the middle 2 numbers (again after sorting), if M is even. You have an empty number list at first. Then you can add in + or remove some number from the list. For each add or remove operation, output the median of numbers in the list. + +Example : +For a set of M = 5 numbers {9, 2, 8, 4, 1} the median is the third number in sorted set {1, 2, 4, 8, 9} which is 4. +Similarly, for a set of M = 4, {5, 2, 10, 4}, the median is the average of second and the third element in the sorted +set {2, 4, 5, 10} which is (4+5)/2 = 4.5. + +Input: +The first line is an integer N that indicates the number of operations. Each of the next N lines is either a x or r x . +a x indicates that x is added to the set, and r x indicates that x is removed from the set. +""" +__author__ = 'Danyang' +# from Queue import PriorityQueue # PriorityQueue does not support removal +import heapq + + +class Solution_TLE(object): + def __init__(self): + self.heap = [] + + def solve(self, cipher): + """ + Heap + + :param cipher: the cipher + """ + op = cipher[0] + num = int(cipher[1]) + if op == "r": + try: + self.heap.remove(num) + except ValueError: + return "Wrong!" + heapq.heapify(self.heap) + else: + heapq.heappush(self.heap, num) + + length = len(self.heap) + if not self.heap: + return "Wrong!" + pq = list(self.heap) + pq = [heapq.heappop(pq) for _ in xrange(length)] + if length & 1 == 0: + return 0.5 * (pq[length / 2 - 1] + pq[length / 2]) + else: + return pq[length / 2] + + +class Solution_TLE2(object): + def __init__(self): + self.min_heap = [] + self.max_heap = [] # no max heap in Python + + def solve(self, cipher): + """ + Median_Heap + + Still TLE + Notice that 6, 7, 8 test cases time out + + :param cipher: the cipher + """ + op = cipher[0] + num = int(cipher[1]) + if op == "r": + try: + # if self.max_heap and -num>self.max_heap[0]: + if self.min_heap and num >= self.min_heap[0]: + self.min_heap.remove(num) + heapq.heapify(self.min_heap) + else: + self.max_heap.remove(-num) + heapq.heapify(self.max_heap) + if not self.min_heap and not self.max_heap: + return "Wrong!" + self.__balance() + except ValueError: + return "Wrong!" + else: + # if self.max_heap and -num>self.max_heap[0]: + if self.min_heap and num >= self.min_heap[0]: + heapq.heappush(self.min_heap, num) + else: + heapq.heappush(self.max_heap, -num) + self.__balance() + + # return "%g"%self.__get_median() # %g rather than %s to avoid trailing zero # general format # fail + output = str(self.__get_median()) + if output[-2:] == ".0": + output = output[:-2] + return output + + def __balance(self): + if len(self.min_heap) > len(self.max_heap) + 1: + item = heapq.heappop(self.min_heap) + heapq.heappush(self.max_heap, -item) + return + if len(self.max_heap) > len(self.min_heap) + 1: + item = heapq.heappop(self.max_heap) + heapq.heappush(self.min_heap, -item) + return + + def __get_median(self): + if len(self.min_heap) == len(self.max_heap): + return 0.5 * (self.min_heap[0] + (-1) * self.max_heap[0]) + elif len(self.min_heap) > len(self.max_heap): + return self.min_heap[0] + else: + return -self.max_heap[0] + + +from bisect import bisect_left + + +class Solution(object): + def __init__(self): + self.A = [] + + def solve(self, cipher): + """ + bisect + """ + op = cipher[0] + val = int(cipher[1]) + + pos = bisect_left(self.A, val) + if op == "r": + if pos >= len(self.A) or self.A[pos] != val: + return "Wrong!" + else: + del (self.A[pos]) + else: # "a" + self.A.insert(pos, val) + + l = len(self.A) + if l == 0: + return "Wrong!" + elif l & 1 == 1: + return self.A[l / 2] + else: + output = str(0.5 * (self.A[l / 2 - 1] + self.A[l / 2])) + if output[-2:] == ".0": + output = output[:-2] + return output + + +if __name__ == "__main__": + import sys + + f = open("0.in", "r") + # f = sys.stdin + testcases = int(f.readline().strip()) + solution = Solution() + for t in xrange(testcases): + # construct cipher + cipher = f.readline().strip().split(' ') + + # solve + s = "%s\n" % (solution.solve(cipher)) + print s, diff --git a/Missing Numbers.py b/Missing Numbers.py index 3b68d01..c3f17a7 100644 --- a/Missing Numbers.py +++ b/Missing Numbers.py @@ -1,50 +1,50 @@ -""" -Problem Statement - -Numeros, The Artist, had two lists A and B, such that, B was a permutation of A. Numeros was very proud of these lists. -Unfortunately, while transporting them from one exhibition to another, some numbers from List A got left out. Can you -find out the numbers missing from A? -""" -__author__ = 'Danyang' - - -class Solution(object): - def solve(self, cipher): - """ - - :param cipher: the cipher - """ - m, A, n, B = cipher - - result = set() # {} is for dictionary - hm = {} - for a in A: - if a not in hm: - hm[a] = 1 - else: - hm[a] += 1 - - for b in B: - if b not in hm or hm[b]<=0: - result.add(b) - else: - hm[b] -= 1 - result = sorted(list(result)) - return " ".join(map(str, result)) - - -if __name__=="__main__": - import sys - - f = open("1.in", "r") - # f = sys.stdin - solution = Solution() - m = int(f.readline().strip()) - A = map(int, f.readline().strip().split(' ')) - n = int(f.readline().strip()) - B = map(int, f.readline().strip().split(' ')) - - cipher = m, A, n, B - # solve - s = "%s\n"%(solution.solve(cipher)) - print s, \ No newline at end of file +""" +Problem Statement + +Numeros, The Artist, had two lists A and B, such that, B was a permutation of A. Numeros was very proud of these lists. +Unfortunately, while transporting them from one exhibition to another, some numbers from List A got left out. Can you +find out the numbers missing from A? +""" +__author__ = 'Danyang' + + +class Solution(object): + def solve(self, cipher): + """ + + :param cipher: the cipher + """ + m, A, n, B = cipher + + result = set() # {} is for dictionary + hm = {} + for a in A: + if a not in hm: + hm[a] = 1 + else: + hm[a] += 1 + + for b in B: + if b not in hm or hm[b] <= 0: + result.add(b) + else: + hm[b] -= 1 + result = sorted(list(result)) + return " ".join(map(str, result)) + + +if __name__ == "__main__": + import sys + + f = open("1.in", "r") + # f = sys.stdin + solution = Solution() + m = int(f.readline().strip()) + A = map(int, f.readline().strip().split(' ')) + n = int(f.readline().strip()) + B = map(int, f.readline().strip().split(' ')) + + cipher = m, A, n, B + # solve + s = "%s\n" % (solution.solve(cipher)) + print s, diff --git a/Number List.py b/Number List.py index e7d3d4c..1f0ebd4 100644 --- a/Number List.py +++ b/Number List.py @@ -43,24 +43,24 @@ def solve(self, cipher): :param cipher: the cipher """ N, K, A = cipher - total = N*(N+1)/2 + total = N * (N + 1) / 2 total_only_s = 0 i = 0 - while iK: + while i < N: + if A[i] > K: i += 1 else: - j = i+1 - while j=end: - return -1 - - def __is_palindrome(self, s): - return s==s[::-1] - - -if __name__=="__main__": - import sys - - f = open("1.in", "r") - # f = sys.stdin - testcases = int(f.readline().strip()) - - for t in xrange(testcases): - # construct cipher - cipher = f.readline().strip() - - # solve - s = "%s\n"%(Solution().solve(cipher)) - print s, \ No newline at end of file +""" +You are given a string of lowercase letters. Your task is to figure out the index of the character on whose removal will +make the string a palindrome. There will always be a valid solution. + +In case string is already palindrome, then -1 is also a valid answer along with possible indices. + +Input Format +The first line contains T i.e. number of test cases. +T lines follow, each line containing a string. +""" +__author__ = 'Danyang' + + +class Solution_TLE(object): + def solve(self, cipher): + """ + Algorithm: + brutal force. O(N^2) + Non-brainer + :param cipher: the cipher + """ + for i in xrange(len(cipher)): + if self.__is_palindrome(cipher[:i] + cipher[i + 1:]): + return i + + return -1 + + def __is_palindrome(self, s): + return s == s[::-1] + + +class Solution(object): + def solve(self, cipher): + """ + Algorithm: + Guarantee one and only one answer + O(N) + :param cipher: the cipher + """ + l = len(cipher) + start = 0 + end = l - 1 + while start < end and cipher[start] == cipher[end]: + start += 1 + end -= 1 + + if self.__is_palindrome(cipher[:start] + cipher[start + 1:]): + return start + if self.__is_palindrome(cipher[:end] + cipher[end + 1:]): + return end + + if start >= end: + return -1 + + def __is_palindrome(self, s): + return s == s[::-1] + + +if __name__ == "__main__": + import sys + + f = open("1.in", "r") + # f = sys.stdin + testcases = int(f.readline().strip()) + + for t in xrange(testcases): + # construct cipher + cipher = f.readline().strip() + + # solve + s = "%s\n" % (Solution().solve(cipher)) + print s, diff --git a/Pangrams.py b/Pangrams.py index 63d656c..fac3751 100644 --- a/Pangrams.py +++ b/Pangrams.py @@ -1,53 +1,53 @@ -""" -Roy wanted to increase his typing speed for programming contests. So, his friend advised him to type the sentence "The -quick brown fox jumps over the lazy dog" repeatedly because it is a pangram. ( pangrams are sentences constructed by -using every letter of the alphabet at least once. ) - -After typing the sentence several times, Roy became bored with it. So he started to look for other pangrams. - -Given a sentence s, tell Roy if it is a pangram or not. - -Input Format - -Input consists of a line containing s. -""" -__author__ = 'Danyang' - - -class Solution(object): - def solve(self, cipher): - """ - Algorithm: - bucket, O(N). Non-brainer - :param cipher: the cipher - """ - bucket = [False for _ in xrange(26)] - for char in cipher: - char = char.lower() - ind = ord(char)-ord('a') - try: - bucket[ind] = True - except IndexError: - pass - - is_pangram = all(bucket) - if is_pangram: - return "pangram" - else: - return "not pangram" - - -if __name__=="__main__": - import sys - - f = open("1.in", "r") - # f = sys.stdin - testcases = 1 - - for t in xrange(testcases): - # construct cipher - cipher = f.readline().strip() - - # solve - s = "%s\n"%(Solution().solve(cipher)) - print s, \ No newline at end of file +""" +Roy wanted to increase his typing speed for programming contests. So, his friend advised him to type the sentence "The +quick brown fox jumps over the lazy dog" repeatedly because it is a pangram. ( pangrams are sentences constructed by +using every letter of the alphabet at least once. ) + +After typing the sentence several times, Roy became bored with it. So he started to look for other pangrams. + +Given a sentence s, tell Roy if it is a pangram or not. + +Input Format + +Input consists of a line containing s. +""" +__author__ = 'Danyang' + + +class Solution(object): + def solve(self, cipher): + """ + Algorithm: + bucket, O(N). Non-brainer + :param cipher: the cipher + """ + bucket = [False for _ in xrange(26)] + for char in cipher: + char = char.lower() + ind = ord(char) - ord('a') + try: + bucket[ind] = True + except IndexError: + pass + + is_pangram = all(bucket) + if is_pangram: + return "pangram" + else: + return "not pangram" + + +if __name__ == "__main__": + import sys + + f = open("1.in", "r") + # f = sys.stdin + testcases = 1 + + for t in xrange(testcases): + # construct cipher + cipher = f.readline().strip() + + # solve + s = "%s\n" % (Solution().solve(cipher)) + print s, diff --git a/Picking Cards.py b/Picking Cards.py index 42c31ff..9d33fa8 100644 --- a/Picking Cards.py +++ b/Picking Cards.py @@ -1,57 +1,57 @@ -""" -Problem Statement - -There are N cards on the table and each has a number between 0 and N. Let us denote the number on the ith card by ci. -You want to pick up all the cards. The ith card can be picked up only if at least ci cards have been picked up before -it. (As an example, if a card has a value of 3 on it, you can't pick that card up unless you've already picked up 3 -cards previously) In how many ways can all the cards be picked up? -""" -__author__ = 'Danyang' -MOD = 1000000007 - - -class Solution(object): - def solve(self, cipher): - """ - Multiplication - Algorithms to increment the paths - :param cipher: the cipher - """ - N, A = cipher - cnts = [0 for _ in xrange(N+1)] - for num in A: - cnts[num] += 1 - - if 0 not in cnts: - return 0 - - # set up - result = 1 - paths = cnts[0] - for i in xrange(1, N): - if paths<=0: - return 0 - result *= paths # Multiplication - result %= MOD - paths += cnts[i] - paths -= 1 # fill the hole - - return result - - -if __name__=="__main__": - import sys - - f = open("1.in", "r") - # f = sys.stdin - solution = Solution() - testcases = int(f.readline().strip()) - - for t in xrange(testcases): - # construct cipher - N = int(f.readline().strip()) - A = map(int, f.readline().strip().split(' ')) - cipher = N, A - # solve - s = "%s\n"%(solution.solve(cipher)) - print s, \ No newline at end of file +""" +Problem Statement + +There are N cards on the table and each has a number between 0 and N. Let us denote the number on the ith card by ci. +You want to pick up all the cards. The ith card can be picked up only if at least ci cards have been picked up before +it. (As an example, if a card has a value of 3 on it, you can't pick that card up unless you've already picked up 3 +cards previously) In how many ways can all the cards be picked up? +""" +__author__ = 'Danyang' +MOD = 1000000007 + + +class Solution(object): + def solve(self, cipher): + """ + Multiplication + Algorithms to increment the paths + :param cipher: the cipher + """ + N, A = cipher + cnts = [0 for _ in xrange(N + 1)] + for num in A: + cnts[num] += 1 + + if 0 not in cnts: + return 0 + + # set up + result = 1 + paths = cnts[0] + for i in xrange(1, N): + if paths <= 0: + return 0 + result *= paths # Multiplication + result %= MOD + paths += cnts[i] + paths -= 1 # fill the hole + + return result + + +if __name__ == "__main__": + import sys + + f = open("1.in", "r") + # f = sys.stdin + solution = Solution() + testcases = int(f.readline().strip()) + + for t in xrange(testcases): + # construct cipher + N = int(f.readline().strip()) + A = map(int, f.readline().strip().split(' ')) + cipher = N, A + # solve + s = "%s\n" % (solution.solve(cipher)) + print s, diff --git a/Play Game.py b/Play Game.py index da6c5a4..6d4a46d 100644 --- a/Play Game.py +++ b/Play Game.py @@ -1,74 +1,73 @@ -""" -You and your friend decide to play a game using a stack consisting of N bricks. In this game, you can alternatively -remove 1, 2 or 3 bricks from the top, and the numbers etched on the removed bricks are added to your score. You have to -play so that you obtain the maximum possible score. It is given that your friend will also play optimally and you make -the first move. - -Input Format -First line will contain an integer T i.e. number of test cases. There will be two lines corresponding to each test case: -first line will contain a number N i.e. number of elements in the stack and next line will contain N numbers i.e. -numbers etched on bricks from top to bottom. -""" -__author__ = 'Danyang' - - -class Solution(object): - def solve(self, cipher): - """ - Algorithm: dp - Current score is affect by the 3 moves and the previous corresponding scores - Starting from the bottom of the stack (rather than top as the gaming sequence) - A: f[i][0] - B: f[i][1] - - index starting from 0: - - f[i][0] = max(sum(w[i-k+1, i]) + sum(w[1..i-k]) - f[i-k][1]) w.r.t k - f[i][1] = max(sum(w[i-k+1, i]) + sum(w[1..i-k]) - f[i-k][0]) w.r.t k - - for f[i][1], i>=1 - :param cipher: the cipher - """ - N, v = cipher - v.reverse() # start from the bottom - # sum dp - s = [0 for _ in xrange(N+1)] - for i in xrange(1, N+1): - s[i] = s[i-1]+v[i-1] - - f = [[0, 0] for _ in xrange(N+1)] - for i in xrange(1, N+1): - # f[i][0] - local_max = 0 - for k in xrange(1, 4): - if i-k>=0: - local_max = max(local_max, s[i]-s[i-k]+s[i-k]-f[i-k][1]) - f[i][0] = local_max - - - # if i==1: continue # starting from the bottom - # f[i][1] - local_max = 0 - for k in xrange(1, 4): - if i-k>=0: - local_max = max(local_max, s[i]-s[i-k]+s[i-k]-f[i-k][0]) - f[i][1] = local_max - - return f[-1][0] - - -if __name__=="__main__": - import sys - - f = open("1.in", "r") - # f = sys.stdin - testcases = int(f.readline().strip()) - - for t in xrange(testcases): - # construct cipher - N = int(f.readline().strip()) - lst = map(lambda x: int(x), f.readline().strip().split(" ")) - cipher = [N, lst] - # solve - s = "%s\n"%(Solution().solve(cipher)) - print s, \ No newline at end of file +""" +You and your friend decide to play a game using a stack consisting of N bricks. In this game, you can alternatively +remove 1, 2 or 3 bricks from the top, and the numbers etched on the removed bricks are added to your score. You have to +play so that you obtain the maximum possible score. It is given that your friend will also play optimally and you make +the first move. + +Input Format +First line will contain an integer T i.e. number of test cases. There will be two lines corresponding to each test case: +first line will contain a number N i.e. number of elements in the stack and next line will contain N numbers i.e. +numbers etched on bricks from top to bottom. +""" +__author__ = 'Danyang' + + +class Solution(object): + def solve(self, cipher): + """ + Algorithm: dp + Current score is affect by the 3 moves and the previous corresponding scores + Starting from the bottom of the stack (rather than top as the gaming sequence) + A: f[i][0] + B: f[i][1] + + index starting from 0: + + f[i][0] = max(sum(w[i-k+1, i]) + sum(w[1..i-k]) - f[i-k][1]) w.r.t k + f[i][1] = max(sum(w[i-k+1, i]) + sum(w[1..i-k]) - f[i-k][0]) w.r.t k + + for f[i][1], i>=1 + :param cipher: the cipher + """ + N, v = cipher + v.reverse() # start from the bottom + # sum dp + s = [0 for _ in xrange(N + 1)] + for i in xrange(1, N + 1): + s[i] = s[i - 1] + v[i - 1] + + f = [[0, 0] for _ in xrange(N + 1)] + for i in xrange(1, N + 1): + # f[i][0] + local_max = 0 + for k in xrange(1, 4): + if i - k >= 0: + local_max = max(local_max, s[i] - s[i - k] + s[i - k] - f[i - k][1]) + f[i][0] = local_max + + # if i==1: continue # starting from the bottom + # f[i][1] + local_max = 0 + for k in xrange(1, 4): + if i - k >= 0: + local_max = max(local_max, s[i] - s[i - k] + s[i - k] - f[i - k][0]) + f[i][1] = local_max + + return f[-1][0] + + +if __name__ == "__main__": + import sys + + f = open("1.in", "r") + # f = sys.stdin + testcases = int(f.readline().strip()) + + for t in xrange(testcases): + # construct cipher + N = int(f.readline().strip()) + lst = map(lambda x: int(x), f.readline().strip().split(" ")) + cipher = [N, lst] + # solve + s = "%s\n" % (Solution().solve(cipher)) + print s, diff --git a/Polar Angles.py b/Polar Angles.py index 0c7aaaf..56a8d0b 100644 --- a/Polar Angles.py +++ b/Polar Angles.py @@ -1,99 +1,100 @@ -""" -A point (x,y), on the cartesian plane, makes an angle theta with the positive direction of the x-axis. Theta varies in -the interval [0 ,2PI) radians, i.e, greater than or equal to zero; but less than 2*PI radians. - -For example, the polar angle of the point (1,2) as marked in this plane below, is (approximately) 63.4 degrees (multiply -by PI/180 to convert to radians) - -Ref http://eldar.mathstat.uoguelph.ca/dashlock/Outreach/Articles/images/PRfig1.jpg - -The Task - -Given a list of points in the 2D plane, sort them in ascending order of their polar angle. In case multiple points share -exactly the same polar angle, the one with lesser distance from the origin (0,0) should occur earlier in the sorted list. - -Input Format -The first line contains an integer N. -This is followed by N lines containing pairs of space separated integers, x and y which represent the coordinates of the -points in the cartesian plane. -""" -__author__ = 'Danyang' -import math - - -class Solution(object): - def solve(self, cipher): - """ - main solution function - :param cipher: the cipher - """ - cipher.sort(cmp=self.cmp) - - - def cmp_polar(self, a, b): - """ - cross product, but what if \pi? - error, can only sort by clockwise - """ - x1 = a[0] - y1 = a[1] - x2 = b[0] - y2 = b[1] - # (0, 0) as anchor point - cross_product = x1*y2-x2*y1 - if cross_product>0: - return -1 - elif cross_product<0: - return 1 - else: - if x1*x1>=0 and y1*y1>=0: - return x1*x1+y1*y1-x2*x2-y2*y2 - else: - if y1>0: - return -1 - if y2>0: - return 1 - if y1==0 and x1>0: - return -1 - else: - return 1 - - def cmp(self, a, b): - """ - polar coordinate - """ - x1 = a[0] - y1 = a[1] - x2 = b[0] - y2 = b[1] - r1 = x1*x1+y1*y1 - r2 = x2*x2+y2*y2 - phi1 = math.atan2(y1, x1) - phi2 = math.atan2(y2, x2) - if phi1<0: - phi1 += math.pi*2 - if phi2<0: - phi2 += math.pi*2 - if phi1phi2: - return 1 - else: - return r1-r2 - - -if __name__=="__main__": - import sys - - f = open("1.in", "r") - # f = sys.stdin - N = int(f.readline().strip()) - - cipher = [] - for t in xrange(N): - # construct cipher - cipher.append(map(int, f.readline().strip().split(' '))) - # solve - Solution().solve(cipher) - for point in cipher: - print "%d %d"%(point[0], point[1]) +""" +A point (x,y), on the cartesian plane, makes an angle theta with the positive direction of the x-axis. Theta varies in +the interval [0 ,2PI) radians, i.e, greater than or equal to zero; but less than 2*PI radians. + +For example, the polar angle of the point (1,2) as marked in this plane below, is (approximately) 63.4 degrees (multiply +by PI/180 to convert to radians) + +Ref http://eldar.mathstat.uoguelph.ca/dashlock/Outreach/Articles/images/PRfig1.jpg + +The Task + +Given a list of points in the 2D plane, sort them in ascending order of their polar angle. In case multiple points share +exactly the same polar angle, the one with lesser distance from the origin (0,0) should occur earlier in the sorted list. + +Input Format +The first line contains an integer N. +This is followed by N lines containing pairs of space separated integers, x and y which represent the coordinates of the +points in the cartesian plane. +""" +import math + +__author__ = 'Danyang' + + +class Solution(object): + def solve(self, cipher): + """ + main solution function + :param cipher: the cipher + """ + cipher.sort(cmp=self.cmp) + + + def cmp_polar(self, a, b): + """ + cross product, but what if \pi? + error, can only sort by clockwise + """ + x1 = a[0] + y1 = a[1] + x2 = b[0] + y2 = b[1] + # (0, 0) as anchor point + cross_product = x1 * y2 - x2 * y1 + if cross_product > 0: + return -1 + elif cross_product < 0: + return 1 + else: + if x1 * x1 >= 0 and y1 * y1 >= 0: + return x1 * x1 + y1 * y1 - x2 * x2 - y2 * y2 + else: + if y1 > 0: + return -1 + if y2 > 0: + return 1 + if y1 == 0 and x1 > 0: + return -1 + else: + return 1 + + def cmp(self, a, b): + """ + polar coordinate + """ + x1 = a[0] + y1 = a[1] + x2 = b[0] + y2 = b[1] + r1 = x1 * x1 + y1 * y1 + r2 = x2 * x2 + y2 * y2 + phi1 = math.atan2(y1, x1) + phi2 = math.atan2(y2, x2) + if phi1 < 0: + phi1 += math.pi * 2 + if phi2 < 0: + phi2 += math.pi * 2 + if phi1 < phi2: + return -1 + elif phi1 > phi2: + return 1 + else: + return r1 - r2 + + +if __name__ == "__main__": + import sys + + f = open("1.in", "r") + # f = sys.stdin + N = int(f.readline().strip()) + + cipher = [] + for t in xrange(N): + # construct cipher + cipher.append(map(int, f.readline().strip().split(' '))) + # solve + Solution().solve(cipher) + for point in cipher: + print "%d %d" % (point[0], point[1]) diff --git a/Possible Path.py b/Possible Path.py index 84ec4e3..73e696c 100644 --- a/Possible Path.py +++ b/Possible Path.py @@ -1,51 +1,51 @@ -# -*- coding: utf-8 -*- -""" -Problem Statement - -Adam is standing at point (a,b) in an infinite 2D grid. He wants to know if he can reach point (x,y) or not. The only -operation he can do is to move to point (a+b,b), (a,a+b), (a-b,b), or (a,a-b) from some point (a,b). It is given that he -can move to any point on this 2D grid,i.e., the points having positive or negative X(or Y) co-ordinates. - -Tell Adam whether he can reach (x,y) or not. - -Input Format -The first line contains an integer, T, followed by T lines, each containing 4 space separated integers i.e. a b x y - -Output Format -For each test case, display YES or NO that indicates if Adam can reach (x,y) or not. -""" -__author__ = 'Danyang' - - -class Solution(object): - def solve(self, cipher): - """ - Algorithm: math: https://hr-filepicker.s3.amazonaws.com/infinitum-jun14/editorials/2372-possible-path.pdf - :param cipher: the cipher - """ - a, b, x, y = cipher - if self.gcd(a, b)==self.gcd(x, y): - return "YES" - else: - return "NO" - - def gcd(self, a, b): - while b: - a, b = b, a%b - return a - - -if __name__=="__main__": - import sys - - f = open("1.in", "r") - # f = sys.stdin - testcases = int(f.readline().strip()) - - for t in xrange(testcases): - # construct cipher - cipher = map(int, f.readline().strip().split(' ')) - - # solve - s = "%s\n"%(Solution().solve(cipher)) - print s, \ No newline at end of file +# -*- coding: utf-8 -*- +""" +Problem Statement + +Adam is standing at point (a,b) in an infinite 2D grid. He wants to know if he can reach point (x,y) or not. The only +operation he can do is to move to point (a+b,b), (a,a+b), (a-b,b), or (a,a-b) from some point (a,b). It is given that he +can move to any point on this 2D grid,i.e., the points having positive or negative X(or Y) co-ordinates. + +Tell Adam whether he can reach (x,y) or not. + +Input Format +The first line contains an integer, T, followed by T lines, each containing 4 space separated integers i.e. a b x y + +Output Format +For each test case, display YES or NO that indicates if Adam can reach (x,y) or not. +""" +__author__ = 'Danyang' + + +class Solution(object): + def solve(self, cipher): + """ + Algorithm: math: https://hr-filepicker.s3.amazonaws.com/infinitum-jun14/editorials/2372-possible-path.pdf + :param cipher: the cipher + """ + a, b, x, y = cipher + if self.gcd(a, b) == self.gcd(x, y): + return "YES" + else: + return "NO" + + def gcd(self, a, b): + while b: + a, b = b, a % b + return a + + +if __name__ == "__main__": + import sys + + f = open("1.in", "r") + # f = sys.stdin + testcases = int(f.readline().strip()) + + for t in xrange(testcases): + # construct cipher + cipher = map(int, f.readline().strip().split(' ')) + + # solve + s = "%s\n" % (Solution().solve(cipher)) + print s, diff --git a/Priyanka and Toys.py b/Priyanka and Toys.py index 2c45286..77a86ab 100644 --- a/Priyanka and Toys.py +++ b/Priyanka and Toys.py @@ -28,15 +28,15 @@ def solve(self, cipher): cur = -5 cnt = 0 for a in A: - if cur+41) which divides all elements of B. Note that x may or may not be an element of A. -Input Format -First line contains T, the number of testcases. Each testcase consists of N in one line. The next line contains -N integers denoting the array A. -""" -__author__ = 'Danyang' - - -class Solution(object): - def solve(self, cipher): - """ - main solution function - :param cipher: the cipher - """ - N, lst = cipher - for i in xrange(N): - for j in xrange(i+1, N): - if self.gcd(lst[i], lst[j])==1: - return "YES" - return "NO" - - def gcd(self, a, b): - while b: - a, b = b, a%b - return a - - -if __name__=="__main__": - import sys - - f = open("1.in", "r") - # f = sys.stdin - testcases = int(f.readline().strip()) - - for t in xrange(testcases): - # construct cipher - N = int(f.readline().strip()) - lst = map(int, f.readline().strip().split(' ')) - cipher = (N, lst) - # solve - s = "%s\n"%(Solution().solve(cipher)) - print s, \ No newline at end of file +""" +Sherlock is stuck. He has an array A1,A2, ..., AN. He wants to know if there exists a subset, B={Ai1,Ai2,...,Aik} +where 1<=i11) which divides all elements of B. Note that x may or may not be an element of A. +Input Format +First line contains T, the number of testcases. Each testcase consists of N in one line. The next line contains +N integers denoting the array A. +""" +__author__ = 'Danyang' + + +class Solution(object): + def solve(self, cipher): + """ + main solution function + :param cipher: the cipher + """ + N, lst = cipher + for i in xrange(N): + for j in xrange(i + 1, N): + if self.gcd(lst[i], lst[j]) == 1: + return "YES" + return "NO" + + def gcd(self, a, b): + while b: + a, b = b, a % b + return a + + +if __name__ == "__main__": + import sys + + f = open("1.in", "r") + # f = sys.stdin + testcases = int(f.readline().strip()) + + for t in xrange(testcases): + # construct cipher + N = int(f.readline().strip()) + lst = map(int, f.readline().strip().split(' ')) + cipher = (N, lst) + # solve + s = "%s\n" % (Solution().solve(cipher)) + print s, diff --git a/Sherlock and MiniMax.py b/Sherlock and MiniMax.py index 40aa9ea..4841112 100644 --- a/Sherlock and MiniMax.py +++ b/Sherlock and MiniMax.py @@ -1,86 +1,86 @@ -# -*- coding: utf-8 -*- -""" -Watson gives Sherlock an array A1,A2...AN. -He asks him to find an integer M between P and Q(both inclusive), such that, min {|Ai-M|, 1 ≤ i ≤ N} is maximised. If -there are multiple solutions, print the smallest one. - -Input Format -The first line contains N. The next line contains space separated N integers, and denote the array A. The third line -contains two space separated integers denoting P and Q. - -Output Format -In one line, print the required answer. - -Constraints -1 ≤ N ≤ 102 -1 ≤ Ai ≤ 109 -1 ≤ P ≤ Q ≤ 109 - -Sample Input - -3 -5 8 14 -4 9 - -5 -12 10 50 24 40 -9 16 -""" -__author__ = 'Danyang' - - -class Solution(object): - def solve(self, cipher): - """ - main solution function - :param cipher: the cipher - """ - A, P, Q = cipher - A.sort() - - gmax = -1<<32 - M = -1 - if P<=A[0] and gmax=A[-1] and gmaxQ and A[i-1]<=Q<=A[i]: - max_cnd = min(abs(A[i]-Q), abs(A[i-1]-Q)) - if gmax= A[-1] and gmax < Q - A[-1]: + gmax = Q - A[-1] + M = Q + + for i in xrange(1, len(A)): + max_cnd = (A[i] - A[i - 1]) / 2 # max_candidate + if gmax < max_cnd: + M_cnd = (A[i] + A[i - 1]) / 2 + if P <= M_cnd <= Q: + gmax = max_cnd + M = M_cnd + + else: # fall in the middle + if M_cnd > Q and A[i - 1] <= Q <= A[i]: + max_cnd = min(abs(A[i] - Q), abs(A[i - 1] - Q)) + if gmax < max_cnd: + gmax = max_cnd + M = Q + if M_cnd < P and A[i - 1] <= P <= A[i]: + max_cnd = min(abs(A[i] - P), abs(A[i - 1] - P)) + if gmax < max_cnd: + gmax = max_cnd + M = P + return M + + +if __name__ == "__main__": + import sys + + f = open("1.in", "r") + # f = sys.stdin + testcases = int(f.readline().strip()) + + + # construct cipher + lst = map(int, f.readline().strip().split(" ")) + P, Q = map(int, f.readline().strip().split(" ")) + cipher = lst, P, Q + # solve + s = "%s\n" % (Solution().solve(cipher)) + print s, diff --git a/Sherlock and Moving Tiles.py b/Sherlock and Moving Tiles.py index b552bfa..b6da9f3 100644 --- a/Sherlock and Moving Tiles.py +++ b/Sherlock and Moving Tiles.py @@ -24,16 +24,17 @@ def solve(self, cipher): :param cipher: the cipher """ L, S1, S2, qs = cipher - v = abs(S1-S2)/math.sqrt(2) + v = abs(S1 - S2) / math.sqrt(2) rets = [] for q in qs: - t = (L-math.sqrt(q))/v + t = (L - math.sqrt(q)) / v rets.append(t) - return "\n".join(map(lambda x: "%f"%x, rets)) + return "\n".join(map(lambda x: "%f" % x, rets)) -if __name__=="__main__": +if __name__ == "__main__": import sys + f = open("1.in", "r") # f = sys.stdin solution = Solution() @@ -46,5 +47,5 @@ def solve(self, cipher): # construct cipher cipher = L, S1, S2, qs # solve - s = "%s\n"%(solution.solve(cipher)) - print s, \ No newline at end of file + s = "%s\n" % (solution.solve(cipher)) + print s, diff --git a/Sherlock and Pairs.py b/Sherlock and Pairs.py index 859aa6b..0877c22 100644 --- a/Sherlock and Pairs.py +++ b/Sherlock and Pairs.py @@ -1,46 +1,46 @@ -""" -Sherlock is given an array of N integers A0, A1 ... AN-1 by Watson. Now Watson asks Sherlock that how many different -pairs of indices i and j exist such that i is not equal to j but Ai is equal to Aj. - -That is, Sherlock has to count total number of pairs of indices (i, j) where Ai = Aj AND i != j. - -Input Format -First line contains T, the number of testcases. T test case follows. -Each testcase consists of two lines, first line contains an integer N, size of array. -Next line contains N space separated integers. -""" -__author__ = 'Danyang' - - -class Solution(object): - def solve(self, cipher): - """ - Hash - :param cipher: the cipher - """ - hm = {} - cnt = 0 - for ind, val in enumerate(cipher): - if val in hm: - cnt += 2*len(hm[val]) - hm[val].append(ind) - else: - hm[val] = [ind] - return cnt - - -if __name__=="__main__": - import sys - - f = open("1.in", "r") - # f = sys.stdin - testcases = int(f.readline().strip()) - - for t in xrange(testcases): - # construct cipher - N = f.readline().strip() - cipher = map(int, f.readline().strip().split(' ')) - - # solve - s = "%s\n"%(Solution().solve(cipher)) - print s, \ No newline at end of file +""" +Sherlock is given an array of N integers A0, A1 ... AN-1 by Watson. Now Watson asks Sherlock that how many different +pairs of indices i and j exist such that i is not equal to j but Ai is equal to Aj. + +That is, Sherlock has to count total number of pairs of indices (i, j) where Ai = Aj AND i != j. + +Input Format +First line contains T, the number of testcases. T test case follows. +Each testcase consists of two lines, first line contains an integer N, size of array. +Next line contains N space separated integers. +""" +__author__ = 'Danyang' + + +class Solution(object): + def solve(self, cipher): + """ + Hash + :param cipher: the cipher + """ + hm = {} + cnt = 0 + for ind, val in enumerate(cipher): + if val in hm: + cnt += 2 * len(hm[val]) + hm[val].append(ind) + else: + hm[val] = [ind] + return cnt + + +if __name__ == "__main__": + import sys + + f = open("1.in", "r") + # f = sys.stdin + testcases = int(f.readline().strip()) + + for t in xrange(testcases): + # construct cipher + N = f.readline().strip() + cipher = map(int, f.readline().strip().split(' ')) + + # solve + s = "%s\n" % (Solution().solve(cipher)) + print s, diff --git a/Sherlock and The Beast.py b/Sherlock and The Beast.py index 3705590..d7dd97b 100644 --- a/Sherlock and The Beast.py +++ b/Sherlock and The Beast.py @@ -1,39 +1,39 @@ -""" -A 'Decent' Number has - - -3 or 5 or both as its digits. No other digit is allowed. -Number of times 3 appears is divisible by 5. -Number of times 5 appears is divisible by 3. -""" -__author__ = 'Danyang' - - -class Solution(object): - def solve(self, N): - """ - mod - - :param cipher: the cipher - """ - for i in xrange(N/3*3, -1, -3): - if (N-i)%5==0: - return "5"*i+"3"*(N-i) - - return "-1" - - -if __name__=="__main__": - import sys - - f = open("1.in", "r") - # f = sys.stdin - solution = Solution() - testcases = int(f.readline().strip()) - - for t in xrange(testcases): - # construct cipher - cipher = int(f.readline().strip()) - - # solve - s = "%s\n"%(solution.solve(cipher)) - print s, \ No newline at end of file +""" +A 'Decent' Number has - + +3 or 5 or both as its digits. No other digit is allowed. +Number of times 3 appears is divisible by 5. +Number of times 5 appears is divisible by 3. +""" +__author__ = 'Danyang' + + +class Solution(object): + def solve(self, N): + """ + mod + + :param cipher: the cipher + """ + for i in xrange(N / 3 * 3, -1, -3): + if (N - i) % 5 == 0: + return "5" * i + "3" * (N - i) + + return "-1" + + +if __name__ == "__main__": + import sys + + f = open("1.in", "r") + # f = sys.stdin + solution = Solution() + testcases = int(f.readline().strip()) + + for t in xrange(testcases): + # construct cipher + cipher = int(f.readline().strip()) + + # solve + s = "%s\n" % (solution.solve(cipher)) + print s, diff --git a/Sherlock and Watson.py b/Sherlock and Watson.py index 182dc28..40a9527 100644 --- a/Sherlock and Watson.py +++ b/Sherlock and Watson.py @@ -1,48 +1,48 @@ -""" -John Watson performs an operation called Right Circular Rotation on an integer array a0,a1 ... an-1. Right Circular -Rotation transforms the array from a0,a1 ... aN-1 to aN-1,a0,... aN-2. - -He performs the operation K times and tests Sherlock's ability to identify the element at a particular position in the -array. He asks Q queries. Each query consists of one integer x, for which you have to print the element ax. - -Input Format -The first line consists of 3 integers N, K and Q separated by a single space. -The next line contains N space separated integers which indicates the elements of the array A. -Each of the next Q lines contain one integer per line denoting x. -""" -__author__ = 'Danyang' - - -class Solution(object): - def solve(self, cipher): - """ - algorithm: circular: original_index = (i-k)%N - :param cipher: the cipher - """ - N, K, Q, A, q = cipher - - result = [] - for i in q: - result.append(A[(i-K)%N]) - - return "\n".join(map(str, result)) - - -if __name__=="__main__": - import sys - - f = open("1.in", "r") - # f = sys.stdin - N, K, Q = map(int, f.readline().strip().split(' ')) - A = map(int, f.readline().strip().split(' ')) - - q = [] - for i in xrange(Q): - q.append(int(f.readline().strip())) - - cipher = N, K, Q, A, q - - - # solve - s = "%s\n"%(Solution().solve(cipher)) - print s, \ No newline at end of file +""" +John Watson performs an operation called Right Circular Rotation on an integer array a0,a1 ... an-1. Right Circular +Rotation transforms the array from a0,a1 ... aN-1 to aN-1,a0,... aN-2. + +He performs the operation K times and tests Sherlock's ability to identify the element at a particular position in the +array. He asks Q queries. Each query consists of one integer x, for which you have to print the element ax. + +Input Format +The first line consists of 3 integers N, K and Q separated by a single space. +The next line contains N space separated integers which indicates the elements of the array A. +Each of the next Q lines contain one integer per line denoting x. +""" +__author__ = 'Danyang' + + +class Solution(object): + def solve(self, cipher): + """ + algorithm: circular: original_index = (i-k)%N + :param cipher: the cipher + """ + N, K, Q, A, q = cipher + + result = [] + for i in q: + result.append(A[(i - K) % N]) + + return "\n".join(map(str, result)) + + +if __name__ == "__main__": + import sys + + f = open("1.in", "r") + # f = sys.stdin + N, K, Q = map(int, f.readline().strip().split(' ')) + A = map(int, f.readline().strip().split(' ')) + + q = [] + for i in xrange(Q): + q.append(int(f.readline().strip())) + + cipher = N, K, Q, A, q + + + # solve + s = "%s\n" % (Solution().solve(cipher)) + print s, diff --git a/Sherlock and permutations.py b/Sherlock and permutations.py index da8e7c5..f7a6d2a 100644 --- a/Sherlock and permutations.py +++ b/Sherlock and permutations.py @@ -1,42 +1,42 @@ -""" -Problem Statement - -Watson asks Sherlock: -Given a string S of N 0's and M 1's, how many unique permutations of this string start with 1? - -Help Sherlock by printing the answer modulo (109+7). - -Input Format -First line contains T, the number of test cases. -Each test case consists of N and M separated by a space. -""" -MOD = 10**9+7 -import math - -__author__ = 'Danyang' - - -class Solution(object): - def solve(self, cipher): - """ - Labeled permutation variants - :param cipher: the cipher - """ - N, M = cipher - return math.factorial(N+M-1)/math.factorial(N)/math.factorial(M-1)%MOD - - -if __name__=="__main__": - import sys - - f = open("1.in", "r") - # f = sys.stdin - testcases = int(f.readline().strip()) - - for t in xrange(testcases): - # construct cipher - cipher = map(int, f.readline().strip().split(' ')) - - # solve - s = "%s\n"%(Solution().solve(cipher)) - print s, \ No newline at end of file +""" +Problem Statement + +Watson asks Sherlock: +Given a string S of N 0's and M 1's, how many unique permutations of this string start with 1? + +Help Sherlock by printing the answer modulo (109+7). + +Input Format +First line contains T, the number of test cases. +Each test case consists of N and M separated by a space. +""" +MOD = 10 ** 9 + 7 +import math + +__author__ = 'Danyang' + + +class Solution(object): + def solve(self, cipher): + """ + Labeled permutation variants + :param cipher: the cipher + """ + N, M = cipher + return math.factorial(N + M - 1) / math.factorial(N) / math.factorial(M - 1) % MOD + + +if __name__ == "__main__": + import sys + + f = open("1.in", "r") + # f = sys.stdin + testcases = int(f.readline().strip()) + + for t in xrange(testcases): + # construct cipher + cipher = map(int, f.readline().strip().split(' ')) + + # solve + s = "%s\n" % (Solution().solve(cipher)) + print s, diff --git a/Special Multiple.py b/Special Multiple.py index 10f0340..9459b2a 100644 --- a/Special Multiple.py +++ b/Special Multiple.py @@ -1,52 +1,52 @@ -""" -Problem Statement - -You are given an integer N. Can you find the least positive integer X made up of only 9's and 0's, such that, X is a -multiple of N? - -Update - -X is made up of one or more occurences of 9 and zero or more occurences of 0. - -Input Format -The first line contains an integer T which denotes the number of test cases. T lines follow. -Each line contains the integer N for which the solution has to be found. - -Output Format -Print the answer X to STDOUT corresponding to each test case. The output should not contain any leading zeroes. -""" -__author__ = 'Danyang' - - -class Solution(object): - def solve(self, cipher): - """ - main solution function - :param cipher: the cipher - """ - N = cipher - - x = 1 - while True: # shortcut: while int(str(bin(x)[2:]))%N!=0 - binary = bin(x)[2:] - nine_ary = str(binary).replace("1", "9") - dec = int(nine_ary) - if dec%N==0: - return dec - x += 1 - - -if __name__=="__main__": - import sys - - f = open("1.in", "r") - # f = sys.stdin - testcases = int(f.readline().strip()) - - for t in xrange(testcases): - # construct cipher - cipher = int(f.readline().strip()) - - # solve - s = "%s\n"%(Solution().solve(cipher)) - print s, \ No newline at end of file +""" +Problem Statement + +You are given an integer N. Can you find the least positive integer X made up of only 9's and 0's, such that, X is a +multiple of N? + +Update + +X is made up of one or more occurences of 9 and zero or more occurences of 0. + +Input Format +The first line contains an integer T which denotes the number of test cases. T lines follow. +Each line contains the integer N for which the solution has to be found. + +Output Format +Print the answer X to STDOUT corresponding to each test case. The output should not contain any leading zeroes. +""" +__author__ = 'Danyang' + + +class Solution(object): + def solve(self, cipher): + """ + main solution function + :param cipher: the cipher + """ + N = cipher + + x = 1 + while True: # shortcut: while int(str(bin(x)[2:]))%N!=0 + binary = bin(x)[2:] + nine_ary = str(binary).replace("1", "9") + dec = int(nine_ary) + if dec % N == 0: + return dec + x += 1 + + +if __name__ == "__main__": + import sys + + f = open("1.in", "r") + # f = sys.stdin + testcases = int(f.readline().strip()) + + for t in xrange(testcases): + # construct cipher + cipher = int(f.readline().strip()) + + # solve + s = "%s\n" % (Solution().solve(cipher)) + print s, diff --git a/Stock Maximize.py b/Stock Maximize.py index 79d6fae..a01f7ba 100644 --- a/Stock Maximize.py +++ b/Stock Maximize.py @@ -22,18 +22,20 @@ def solve(self, cipher): """ N, A = cipher f = [0 for _ in A] - f[N-1] = A[N-1] - for i in xrange(N-2, -1, -1): - f[i] = max(A[i], f[i+1]) + f[N - 1] = A[N - 1] + for i in xrange(N - 2, -1, -1): + f[i] = max(A[i], f[i + 1]) profit = 0 - for i in xrange(N-1): - profit += max(0, f[i+1]-A[i]) + for i in xrange(N - 1): + profit += max(0, f[i + 1] - A[i]) return profit -if __name__=="__main__": + +if __name__ == "__main__": import sys + f = open("0.in", "r") # f = sys.stdin solution = Solution() @@ -45,5 +47,5 @@ def solve(self, cipher): A = map(int, f.readline().strip().split(' ')) cipher = N, A # solve - s = "%s\n"%(solution.solve(cipher)) - print s, \ No newline at end of file + s = "%s\n" % (solution.solve(cipher)) + print s, diff --git a/Strange Grid.py b/Strange Grid.py index 0a9ff1e..bf674d6 100644 --- a/Strange Grid.py +++ b/Strange Grid.py @@ -30,13 +30,14 @@ def solve(self, cipher): :param cipher: the cipher """ r, c = cipher - r, c = r-1, c-1 + r, c = r - 1, c - 1 - return r/2*10+r%2+c*2 + return r / 2 * 10 + r % 2 + c * 2 -if __name__=="__main__": +if __name__ == "__main__": import sys + f = open("0.in", "r") # f = sys.stdin solution = Solution() @@ -44,5 +45,5 @@ def solve(self, cipher): cipher = map(int, f.readline().strip().split(' ')) # solve - s = "%s\n"%(solution.solve(cipher)) - print s, \ No newline at end of file + s = "%s\n" % (solution.solve(cipher)) + print s, diff --git a/Substring Diff.py b/Substring Diff.py index 72eea96..f7e57ad 100644 --- a/Substring Diff.py +++ b/Substring Diff.py @@ -1,84 +1,83 @@ -""" -Given two strings of length n, P = p1p2...pn and Q = q1q2...qn, we define M(i,j,k) as the number of mismatches between - p(i), p(i+1), ...p(i+k-1) and q(j), q(j+1)...,q(j+k-1). That is in set notation, M(i,j,k) refers to the size of the set - -{0 <= x < k, p[i+x]| != q[j+x]} -Given an integer S, your task is to find the maximum length L, such that, there exists pair of indices (i,j) for which -we have M(i, j, L) <= S. Of course, we should also have i+L-1 <=n and j+L-1 <=n. - -Input - -The first line of input contains a single integer, T (1 <= T <= 10). T test cases follow. -Each test case consists of an integer, S, and two strings P and Q separated by a single space. -""" -__author__ = 'Danyang' - - -class Solution(object): - def solve(self, cipher): - """ - Algorithm 0: brutal force - O(n^3) - - Algorithm 1: dp - - dp[i][j] is L that make the substring diff <= S - - Diagonal relationship: - dp[i+1][j+1] = dp[i][j] if p[i]==q[i] else dp[i][j]+scan until next difference # but not O(1) - - dp[i][j] = dp[i+1][j+1] if p[i]==q[i] else shrink # but not O(1) - - Algorithm 2: sliding window, shrink and expand # O(1), you do not need the exact intermediate results - :param cipher: the cipher - """ - S, p, q = cipher - n = len(p) - S = int(S) - global_max = 0 - for i in xrange(n): # only need to consider diagonal since scanned by diagonal line - global_max = max(global_max, self.get_longest(S, p, q, i, 0), self.get_longest(S, p, q, 0, i)) - - return global_max - - - def get_longest(self, S, p, q, i, j): - start_i = i - start_j = j - local_max = 0 - n = len(p) - cur_diff = 0 - while iS: # then shrink the left side of window - while p[start_i]==q[start_j]: - start_i += 1 - start_j += 1 - start_i += 1 - start_j += 1 - cur_diff -= 1 - - local_max = max(local_max, i-start_i+1) - - i += 1 - j += 1 - - return local_max - - -if __name__=="__main__": - import sys - - f = open("1.in", "r") - # f = sys.stdin - testcases = int(f.readline().strip()) - - for t in xrange(testcases): - # construct cipher - cipher = f.readline().strip().split(' ') - - # solve - s = "%s\n"%(Solution().solve(cipher)) - print s, \ No newline at end of file +""" +Given two strings of length n, P = p1p2...pn and Q = q1q2...qn, we define M(i,j,k) as the number of mismatches between + p(i), p(i+1), ...p(i+k-1) and q(j), q(j+1)...,q(j+k-1). That is in set notation, M(i,j,k) refers to the size of the set + +{0 <= x < k, p[i+x]| != q[j+x]} +Given an integer S, your task is to find the maximum length L, such that, there exists pair of indices (i,j) for which +we have M(i, j, L) <= S. Of course, we should also have i+L-1 <=n and j+L-1 <=n. + +Input + +The first line of input contains a single integer, T (1 <= T <= 10). T test cases follow. +Each test case consists of an integer, S, and two strings P and Q separated by a single space. +""" +__author__ = 'Danyang' + + +class Solution(object): + def solve(self, cipher): + """ + Algorithm 0: brutal force + O(n^3) + + Algorithm 1: dp + + dp[i][j] is L that make the substring diff <= S + + Diagonal relationship: + dp[i+1][j+1] = dp[i][j] if p[i]==q[i] else dp[i][j]+scan until next difference # but not O(1) + + dp[i][j] = dp[i+1][j+1] if p[i]==q[i] else shrink # but not O(1) + + Algorithm 2: sliding window, shrink and expand # O(1), you do not need the exact intermediate results + :param cipher: the cipher + """ + S, p, q = cipher + n = len(p) + S = int(S) + global_max = 0 + for i in xrange(n): # only need to consider diagonal since scanned by diagonal line + global_max = max(global_max, self.get_longest(S, p, q, i, 0), self.get_longest(S, p, q, 0, i)) + + return global_max + + def get_longest(self, S, p, q, i, j): + start_i = i + start_j = j + local_max = 0 + n = len(p) + cur_diff = 0 + while i < n and j < n: + if p[i] != q[j]: + cur_diff += 1 + + if cur_diff > S: # then shrink the left side of window + while p[start_i] == q[start_j]: + start_i += 1 + start_j += 1 + start_i += 1 + start_j += 1 + cur_diff -= 1 + + local_max = max(local_max, i - start_i + 1) + + i += 1 + j += 1 + + return local_max + + +if __name__ == "__main__": + import sys + + f = open("1.in", "r") + # f = sys.stdin + testcases = int(f.readline().strip()) + + for t in xrange(testcases): + # construct cipher + cipher = f.readline().strip().split(' ') + + # solve + s = "%s\n" % (Solution().solve(cipher)) + print s, diff --git a/Task Scheduling.py b/Task Scheduling.py index 76ac5ef..4688165 100644 --- a/Task Scheduling.py +++ b/Task Scheduling.py @@ -1,50 +1,50 @@ -""" -You have a long list of tasks that you need to do today. To accomplish task i, you need Mi minutes and the deadline for -this task is Di. You need not complete a task at a stretch. You can complete a part of it, switch to another task, and -then switch back. - -You've realized that it might not be possible to complete all the tasks by their deadline. So you decide to do them in -such a manner that the maximum amount by which a task's completion time overshoots its deadline is minimized. - -Input: -The first line contains the number of tasks T. Each of the next T lines contains two integers Di and Mi. -""" -__author__ = 'Danyang' - - -class Solution(object): - def solve(self, cipher): - """ - Small test cases pass. Sort by deadline and complete them one by one - - for complete solution: https://github.com/ningke/tasksched - - main solution function - :param cipher: the cipher - """ - tasks = cipher - tasks.sort(key=lambda t: t[0]) - - overshot = -1 - timer = 0 - for task in tasks: - timer += task[1] - overshot = max(overshot, timer-task[0]) - - return overshot - - -if __name__=="__main__": - import sys - - f = open("1.in", "r") - # f = sys.stdin - testcases = int(f.readline().strip()) - cipher = [] - for t in xrange(testcases): - # construct cipher - cipher.append(map(lambda x: int(x), f.readline().strip().split(' '))) - - # solve - s = "%s\n"%(Solution().solve(cipher)) - print s, \ No newline at end of file +""" +You have a long list of tasks that you need to do today. To accomplish task i, you need Mi minutes and the deadline for +this task is Di. You need not complete a task at a stretch. You can complete a part of it, switch to another task, and +then switch back. + +You've realized that it might not be possible to complete all the tasks by their deadline. So you decide to do them in +such a manner that the maximum amount by which a task's completion time overshoots its deadline is minimized. + +Input: +The first line contains the number of tasks T. Each of the next T lines contains two integers Di and Mi. +""" +__author__ = 'Danyang' + + +class Solution(object): + def solve(self, cipher): + """ + Small test cases pass. Sort by deadline and complete them one by one + + for complete solution: https://github.com/ningke/tasksched + + main solution function + :param cipher: the cipher + """ + tasks = cipher + tasks.sort(key=lambda t: t[0]) + + overshot = -1 + timer = 0 + for task in tasks: + timer += task[1] + overshot = max(overshot, timer - task[0]) + + return overshot + + +if __name__ == "__main__": + import sys + + f = open("1.in", "r") + # f = sys.stdin + testcases = int(f.readline().strip()) + cipher = [] + for t in xrange(testcases): + # construct cipher + cipher.append(map(lambda x: int(x), f.readline().strip().split(' '))) + + # solve + s = "%s\n" % (Solution().solve(cipher)) + print s, diff --git a/The Coin Change Problem.py b/The Coin Change Problem.py index 2ac26ff..7e6124d 100644 --- a/The Coin Change Problem.py +++ b/The Coin Change Problem.py @@ -24,24 +24,25 @@ def solve(self, cipher): :param cipher: the cipher """ total, n, lst = cipher - f = [[0 for _ in xrange(n)] for _ in xrange(total+1)] + f = [[0 for _ in xrange(n)] for _ in xrange(total + 1)] for i in xrange(n): - if lst[i]=0: - f[k][i] += f[k-lst[i]][i] # pick the current coin i - if i+1= 0: + f[k][i] += f[k - lst[i]][i] # pick the current coin i + if i + 1 < n: + f[k][i] += f[k][i + 1] # skip to the next coin return f[total][0] -if __name__=="__main__": +if __name__ == "__main__": import sys + f = open("1.in", "r") # f = sys.stdin solution = Solution() @@ -50,5 +51,5 @@ def solve(self, cipher): cipher = N, M, lst # solve - s = "%s\n"%(solution.solve(cipher)) - print s, \ No newline at end of file + s = "%s\n" % (solution.solve(cipher)) + print s, diff --git a/The Grid Search.py b/The Grid Search.py index 31ba8c2..be60efa 100644 --- a/The Grid Search.py +++ b/The Grid Search.py @@ -1,103 +1,103 @@ -""" -Problem Statement - -Given a 2D array of digits, try to find the location of a given 2D pattern of digits within it. For example, consider -the following 2D matrix. - -1234567890 -0987654321 -1111111111 -1111111111 -2222222222 -If we need to look for the following 2D pattern within it: - -876543 -111111 -111111 -If we scan through the original array, we observe, that 2D pattern begins from the second row and the third column of -the larger grid (the 8 in the second row and third column of the larger grid, is the top-left corner of the pattern we -are searching for). - -So, a 2D pattern of digits P is said to be present in a larger grid G, if the latter contains a contiguous, rectangular -2D grid of digits matching with the pattern P; similar to the example shown above. - -Input Format -The first line contains an integer T, which is the number of tests. T tests follow and the structure of each test is -described below: -The first line contains 2 space separated integers R and C indicating the number of rows and columns in the grid G. -This is followed by R lines, each with a string of C digits each; which represent the grid G. -The second line contains 2 tab separated integers r and c indicating the number of rows and columns in the pattern grid -P. -This is followed by r lines, each with a string of c digits each; which represent the pattern P. -""" -__author__ = 'Danyang' - - -class Solution(object): - def solve(self, cipher): - """ - pre-check pruning - - Typical technique in Matrix (Grid) - dp[i][j] is the sum of the rect from (0, 0) to (i-1, j-1) - - then them sum of the rect from (a, b) to (i, j) can be calculated - :param cipher: the cipher - """ - matrix, pattern = cipher - - R1, C1 = len(matrix), len(matrix[0]) - R2, C2 = len(pattern), len(pattern[0]) - - dp = [[0 for _ in xrange(C1+1)] for _ in xrange(R1+1)] # note the dummies - - for i in xrange(1, R1+1): - for j in xrange(1, C1+1): - dp[i][j] = dp[i-1][j]+dp[i][j-1]-dp[i-1][j-1]+matrix[i-1][j-1] - - pattern_sum = sum([sum(pattern[i]) for i in xrange(R2)]) - - for i in xrange(R1-R2+1): - for j in xrange(C1-C2+1): - # bottom = i+R2+1 # bugs - # left = j+C2+1 - bottom = i+R2 - left = j+C2 - candidate_sum = dp[bottom][left]-dp[bottom][j]-dp[i][left]+dp[i][j] - - if candidate_sum==pattern_sum: - matched = True - for a in xrange(R2): - for b in xrange(C2): - if matrix[i+a][j+b]!=pattern[a][b]: - matched = False - break - if not matched: - break - if matched: - return "YES" - return "NO" - - -if __name__=="__main__": - import sys - - f = open("1.in", "r") - # f = sys.stdin - testcases = int(f.readline().strip()) - - for t in xrange(testcases): - # construct cipher - matrix = [] - pattern = [] - R, C = map(int, f.readline().strip().split(' ')) - for i in xrange(R): - matrix.append(map(int, list(f.readline().strip()))) - R, C = map(int, f.readline().strip().split(' ')) - for i in xrange(R): - pattern.append(map(int, list(f.readline().strip()))) - - cipher = matrix, pattern - # solve - s = "%s\n"%(Solution().solve(cipher)) - print s, \ No newline at end of file +""" +Problem Statement + +Given a 2D array of digits, try to find the location of a given 2D pattern of digits within it. For example, consider +the following 2D matrix. + +1234567890 +0987654321 +1111111111 +1111111111 +2222222222 +If we need to look for the following 2D pattern within it: + +876543 +111111 +111111 +If we scan through the original array, we observe, that 2D pattern begins from the second row and the third column of +the larger grid (the 8 in the second row and third column of the larger grid, is the top-left corner of the pattern we +are searching for). + +So, a 2D pattern of digits P is said to be present in a larger grid G, if the latter contains a contiguous, rectangular +2D grid of digits matching with the pattern P; similar to the example shown above. + +Input Format +The first line contains an integer T, which is the number of tests. T tests follow and the structure of each test is +described below: +The first line contains 2 space separated integers R and C indicating the number of rows and columns in the grid G. +This is followed by R lines, each with a string of C digits each; which represent the grid G. +The second line contains 2 tab separated integers r and c indicating the number of rows and columns in the pattern grid +P. +This is followed by r lines, each with a string of c digits each; which represent the pattern P. +""" +__author__ = 'Danyang' + + +class Solution(object): + def solve(self, cipher): + """ + pre-check pruning + + Typical technique in Matrix (Grid) + dp[i][j] is the sum of the rect from (0, 0) to (i-1, j-1) + + then them sum of the rect from (a, b) to (i, j) can be calculated + :param cipher: the cipher + """ + matrix, pattern = cipher + + R1, C1 = len(matrix), len(matrix[0]) + R2, C2 = len(pattern), len(pattern[0]) + + dp = [[0 for _ in xrange(C1 + 1)] for _ in xrange(R1 + 1)] # note the dummies + + for i in xrange(1, R1 + 1): + for j in xrange(1, C1 + 1): + dp[i][j] = dp[i - 1][j] + dp[i][j - 1] - dp[i - 1][j - 1] + matrix[i - 1][j - 1] + + pattern_sum = sum([sum(pattern[i]) for i in xrange(R2)]) + + for i in xrange(R1 - R2 + 1): + for j in xrange(C1 - C2 + 1): + # bottom = i+R2+1 # bugs + # left = j+C2+1 + bottom = i + R2 + left = j + C2 + candidate_sum = dp[bottom][left] - dp[bottom][j] - dp[i][left] + dp[i][j] + + if candidate_sum == pattern_sum: + matched = True + for a in xrange(R2): + for b in xrange(C2): + if matrix[i + a][j + b] != pattern[a][b]: + matched = False + break + if not matched: + break + if matched: + return "YES" + return "NO" + + +if __name__ == "__main__": + import sys + + f = open("1.in", "r") + # f = sys.stdin + testcases = int(f.readline().strip()) + + for t in xrange(testcases): + # construct cipher + matrix = [] + pattern = [] + R, C = map(int, f.readline().strip().split(' ')) + for i in xrange(R): + matrix.append(map(int, list(f.readline().strip()))) + R, C = map(int, f.readline().strip().split(' ')) + for i in xrange(R): + pattern.append(map(int, list(f.readline().strip()))) + + cipher = matrix, pattern + # solve + s = "%s\n" % (Solution().solve(cipher)) + print s, diff --git a/The Love-Letter Mystery.py b/The Love-Letter Mystery.py index 6e25256..c005d0a 100644 --- a/The Love-Letter Mystery.py +++ b/The Love-Letter Mystery.py @@ -1,55 +1,55 @@ -""" -James found a love letter his friend Harry has written for his girlfriend. James is a prankster, so he decides to meddle - with the letter. He changes all the words in the letter into palindromes. - -To do this, he follows 2 rules: - -(a) He can reduce the value of a letter, e.g. he can change 'd' to 'c', but he cannot change 'c' to 'd'. -(b) In order to form a palindrome, if he has to repeatedly reduce the value of a letter, he can do it until the letter -becomes 'a'. Once a letter has been changed to 'a', it can no longer be changed. - -Each reduction in the value of any letter is counted as a single operation. Find the minimum number of operations -required to convert a given string into a palindrome. - - -Input Format -The first line contains an integer T, i.e., the number of test cases. -The next T lines will contain a string each. The strings do not contain any spaces. -""" -__author__ = 'Danyang' - - -class Solution(object): - def solve(self, cipher): - """ - scan from both sides, doing operation - :param cipher: the cipher - """ - start_ptr = 0 - end_ptr = len(cipher)-1 - - cnt = 0 - while start_ptr0: + if len(ret) > 0: return "YES" else: return "NO" -if __name__=="__main__": +if __name__ == "__main__": import sys + f = open("0.in", "r") # f = sys.stdin solution = Solution() @@ -34,5 +35,5 @@ def solve(self, cipher): cipher.append(f.readline().strip()) cipher.append(f.readline().strip()) # solve - s = "%s\n"%(solution.solve(cipher)) - print s, \ No newline at end of file + s = "%s\n" % (solution.solve(cipher)) + print s, diff --git a/Two Two.py b/Two Two.py index be5eaa4..4fcc511 100644 --- a/Two Two.py +++ b/Two Two.py @@ -1,82 +1,82 @@ -""" -Prof. Twotwo as the name suggests is very fond powers of 2. Moreover he also has special affinity to number 800. He is -known for carrying quirky experiments on powers of 2. - -One day he played a game is his class. He brought some number plates on each of which a digit from 0 to 9 is written. He -made students stand in a row and gave a number plate to each of the student. Now turn by turn, he called for some -students who are standing continuously in the row say from index i to index j (i<=j) and asked them to find their -strength. - -The strength of the group of students from i to j is defined as: - -strength(i , j) -{ - if a[i] = 0 - return 0; //If first child has value 0 in the group, strength of group is zero - value = 0; - for k from i to j - value = value*10 + a[k] - return value; -} -Prof called for all possible combinations of i and j and noted down the strength of each group. Now being interested in -powers of 2, he wants to find out how many strengths are powers of two. Now its your responsibility to get the answer -for prof. - -Input Format -First line contains number of test cases T -Next T line contains the numbers of number plates the students were having when standing in the row in the form of a -string A. -""" -__author__ = 'Danyang' - - -class Solution(object): - def solve_TLE(self, cipher): - """ - main solution function - :param cipher: the cipher - """ - # a = map(lambda x: int(x), list(cipher[0])) - a = cipher[0] - counter = 0 - for i in xrange(len(a)): - if a[i]=="0": - continue - for j in xrange(i, len(a)): - # strength = self.strength(a, i, j) - strength = a[i:j+1] - strength = int(strength) - if strength&(strength-1)==0: - counter += 1 - return counter - - def solve(self, cipher): - """ - main solution function - :param cipher: the cipher - """ - - def strength(self, a, i, j): - # not used - if a[i]==0: - return 0 - value = 0 - for k in xrange(i, j+1): - value = value*10+a[k] - return value - - -if __name__=="__main__": - import sys - - f = open("1.in", "r") - # f = sys.stdin - testcases = int(f.readline().strip()) - - for t in xrange(testcases): - # construct cipher - cipher = f.readline().strip().split(' ') - - # solve - s = "%s\n"%(Solution().solve(cipher)) - print s, \ No newline at end of file +""" +Prof. Twotwo as the name suggests is very fond powers of 2. Moreover he also has special affinity to number 800. He is +known for carrying quirky experiments on powers of 2. + +One day he played a game is his class. He brought some number plates on each of which a digit from 0 to 9 is written. He +made students stand in a row and gave a number plate to each of the student. Now turn by turn, he called for some +students who are standing continuously in the row say from index i to index j (i<=j) and asked them to find their +strength. + +The strength of the group of students from i to j is defined as: + +strength(i , j) +{ + if a[i] = 0 + return 0; //If first child has value 0 in the group, strength of group is zero + value = 0; + for k from i to j + value = value*10 + a[k] + return value; +} +Prof called for all possible combinations of i and j and noted down the strength of each group. Now being interested in +powers of 2, he wants to find out how many strengths are powers of two. Now its your responsibility to get the answer +for prof. + +Input Format +First line contains number of test cases T +Next T line contains the numbers of number plates the students were having when standing in the row in the form of a +string A. +""" +__author__ = 'Danyang' + + +class Solution(object): + def solve_TLE(self, cipher): + """ + main solution function + :param cipher: the cipher + """ + # a = map(lambda x: int(x), list(cipher[0])) + a = cipher[0] + counter = 0 + for i in xrange(len(a)): + if a[i] == "0": + continue + for j in xrange(i, len(a)): + # strength = self.strength(a, i, j) + strength = a[i:j + 1] + strength = int(strength) + if strength & (strength - 1) == 0: + counter += 1 + return counter + + def solve(self, cipher): + """ + main solution function + :param cipher: the cipher + """ + + def strength(self, a, i, j): + # not used + if a[i] == 0: + return 0 + value = 0 + for k in xrange(i, j + 1): + value = value * 10 + a[k] + return value + + +if __name__ == "__main__": + import sys + + f = open("1.in", "r") + # f = sys.stdin + testcases = int(f.readline().strip()) + + for t in xrange(testcases): + # construct cipher + cipher = f.readline().strip().split(' ') + + # solve + s = "%s\n" % (Solution().solve(cipher)) + print s, diff --git a/Two arrays.py b/Two arrays.py index acaff1b..ed22ac5 100644 --- a/Two arrays.py +++ b/Two arrays.py @@ -1,49 +1,49 @@ -""" -ou are given two integer arrays, A and B, each containing N integers. The size of the array is less than or equal to -1000. You are free to permute the order of the elements in the arrays. - -Now here's the real question: Is there an permutation A', B' possible of A and B, such that, A'i+B'i >= K for all i, -where A'i denotes the ith element in the array A' and B'i denotes ith element in the array B'. - - -Input Format -The first line contains an integer, T, the number of test-cases. T test cases follow. Each test case has the following -format: - -The first line contains two integers, N and K. The second line contains N space separated integers, denoting array A. -The third line describes array B in a same format. -""" -__author__ = 'Danyang' - - -class Solution(object): - def solve(self, cipher): - """ - main solution function - :param cipher: the cipher - """ - N, K, A, B = cipher - A.sort() - B.sort(reverse=True) # dynamic typed, then cannot detect list() - for i in xrange(N): - if not A[i]+B[i]>=K: - return "NO" - return "YES" - - -if __name__=="__main__": - import sys - - f = open("1.in", "r") - # f = sys.stdin - testcases = int(f.readline().strip()) - - for t in xrange(testcases): - # construct cipher - N, K = map(int, f.readline().strip().split(" ")) - A = map(int, f.readline().strip().split(' ')) - B = map(int, f.readline().strip().split(' ')) - cipher = N, K, A, B - # solve - s = "%s\n"%(Solution().solve(cipher)) - print s, \ No newline at end of file +""" +ou are given two integer arrays, A and B, each containing N integers. The size of the array is less than or equal to +1000. You are free to permute the order of the elements in the arrays. + +Now here's the real question: Is there an permutation A', B' possible of A and B, such that, A'i+B'i >= K for all i, +where A'i denotes the ith element in the array A' and B'i denotes ith element in the array B'. + + +Input Format +The first line contains an integer, T, the number of test-cases. T test cases follow. Each test case has the following +format: + +The first line contains two integers, N and K. The second line contains N space separated integers, denoting array A. +The third line describes array B in a same format. +""" +__author__ = 'Danyang' + + +class Solution(object): + def solve(self, cipher): + """ + main solution function + :param cipher: the cipher + """ + N, K, A, B = cipher + A.sort() + B.sort(reverse=True) # dynamic typed, then cannot detect list() + for i in xrange(N): + if not A[i] + B[i] >= K: + return "NO" + return "YES" + + +if __name__ == "__main__": + import sys + + f = open("1.in", "r") + # f = sys.stdin + testcases = int(f.readline().strip()) + + for t in xrange(testcases): + # construct cipher + N, K = map(int, f.readline().strip().split(" ")) + A = map(int, f.readline().strip().split(' ')) + B = map(int, f.readline().strip().split(' ')) + cipher = N, K, A, B + # solve + s = "%s\n" % (Solution().solve(cipher)) + print s, diff --git a/Utopian Tree.py b/Utopian Tree.py index fed03af..282b0e6 100644 --- a/Utopian Tree.py +++ b/Utopian Tree.py @@ -1,41 +1,41 @@ -""" -The Utopian tree goes through 2 cycles of growth every year. The first growth cycle occurs during the monsoon, when it -doubles in height. The second growth cycle occurs during the summer, when its height increases by 1 meter. - -Now, a new Utopian tree sapling is planted at the onset of the monsoon. Its height is 1 meter. Can you find the height -of the tree after N growth cycles? -""" -__author__ = 'Danyang' - - -class Solution(object): - def solve(self, cipher): - """ - main solution function - :param cipher: the cipher - """ - N = int(cipher[0]) - # initial = 1 # wrong var name - height = 1 # initialization - for cycle in xrange(N): - if cycle&1==0: - height *= 2 - else: - height += 1 - - return height - - -if __name__=="__main__": - import sys - # f = open("1.in", "r") - f = sys.stdin - testcases = int(f.readline().strip()) - - for t in xrange(testcases): - # construct cipher - cipher = f.readline().strip().split(' ') - - # solve - s = "%s\n"%(Solution().solve(cipher)) - print s, \ No newline at end of file +""" +The Utopian tree goes through 2 cycles of growth every year. The first growth cycle occurs during the monsoon, when it +doubles in height. The second growth cycle occurs during the summer, when its height increases by 1 meter. + +Now, a new Utopian tree sapling is planted at the onset of the monsoon. Its height is 1 meter. Can you find the height +of the tree after N growth cycles? +""" +__author__ = 'Danyang' + + +class Solution(object): + def solve(self, cipher): + """ + main solution function + :param cipher: the cipher + """ + N = int(cipher[0]) + # initial = 1 # wrong var name + height = 1 # initialization + for cycle in xrange(N): + if cycle & 1 == 0: + height *= 2 + else: + height += 1 + + return height + + +if __name__ == "__main__": + import sys + # f = open("1.in", "r") + f = sys.stdin + testcases = int(f.readline().strip()) + + for t in xrange(testcases): + # construct cipher + cipher = f.readline().strip().split(' ') + + # solve + s = "%s\n" % (Solution().solve(cipher)) + print s, diff --git a/Vertical Sticks.py b/Vertical Sticks.py index f29dfa0..b889564 100644 --- a/Vertical Sticks.py +++ b/Vertical Sticks.py @@ -29,20 +29,21 @@ def solve(self, cipher): :param cipher: the cipher """ N, A = cipher - l = N+1 + l = N + 1 E = 0 for cur in A: k = 0 for a in A: - if a>=cur: + if a >= cur: k += 1 # including itself - E += float(l)/(k+1) + E += float(l) / (k + 1) return "%.2f" % E -if __name__=="__main__": +if __name__ == "__main__": import sys + f = open("0.in", "r") # f = sys.stdin solution = Solution() @@ -56,4 +57,4 @@ def solve(self, cipher): # solve s = "%s\n" % (solution.solve(cipher)) - print s, \ No newline at end of file + print s, diff --git a/Xor and Sum.py b/Xor and Sum.py index 9d4633b..d37b1c8 100644 --- a/Xor and Sum.py +++ b/Xor and Sum.py @@ -1,88 +1,88 @@ -""" -You are given two positive integers a and b in binary representation. You should find the following sum modulo 10^9+7: - -\sum_i=0^314159{a xor (b shl i)} -where operation xor means exclusive OR operation, operation shl means binary shift to the left. - -Please note, that we consider ideal model of binary integers. That is there is infinite number of bits in each number, -and there are no disappearings (or cyclic shifts) of bits. - -Input Format - -The first line contains number a (1<=a<2^{10^5}) in binary representation. The second line contains number -b (1<=b<2^{10^5}) in the same format. All the numbers do not contain leading zeros. -""" -__author__ = 'Danyang' -MOD = 10**9+7 -BIT_CNT = 10**5 -SHIFT_CNT = 314159 -# BIT_CNT = 4 # test -# SHIFT_CNT = 4 # test -N = BIT_CNT+SHIFT_CNT - - -class Solution(object): - def solve(self, cipher): - """ - algorithm: dp, bit sum - sum of the number of 1's - sum of the number of 0's - treat a as mask - scrutinize b - :param cipher: the cipher - """ - a, b = cipher - len_a = len(a) - len_b = len(b) - - # bit array - a_array = [0 for _ in xrange(N)] - b_array = [0 for _ in xrange(N)] - - # str to reversed bit array - for ind, val in enumerate(a): - a_array[len_a-1-ind] = int(val) - for ind, val in enumerate(b): - b_array[len_b-1-ind] = int(val) - - # dp for sum of bits - dp = [[0, 0] for _ in xrange(N+1)] - for i in xrange(1, N+1): - dp[i][0] = dp[i-1][0]+1 if b_array[i-1]==0 else dp[i-1][0] - dp[i][1] = dp[i-1][1]+1 if b_array[i-1]==1 else dp[i-1][1] - - result = 0 - sig = 1 - for i in xrange(N): # total N bit - if i