Quantcast
Channel: CodeChef Discuss - latest questions
Viewing all 40121 articles
Browse latest View live

Virtual-Online-Competitive-Judge (Script)

$
0
0

Virtual Online Judge generates a random set of questions from various Online Websites for competitive programming such as Codechef, Codeforces etc. It creates a contest containing five problems sorted by difficulty and a user may submit solutions to these problems in any order. Questions from these websites are scraped and can be viewed by the user on a basic GUI created on python using Tkinter.

Every competitive programmer wants a good mix of questions from different judges and to have a script which would create a completely random contest any number of times would be a delight for a competitive programmer.

Click 'here' to view the Github repository.


Help in Polynomial Multiplication

help in codeforces problem 580/C (Kefa and park).

delay in editorials

$
0
0

Why does codechef take too much time in posting editorials? They should be posted just after the end of contest like in codeforces so that we can find mistake in our approach.

Tutorial - Beginner and Advanced.

Call for Setting Hard Problems At CodeChef

$
0
0

Hi fellow coders,

Here at CodeChef, we believe you’re a great problem setter and would be delighted to have you on our problem setting team. For the upcoming long contests, we are in need of more problems with a higher difficulty level, we hope to find hard problems with non-trivial ideas.. If you have some problems of that level, that would be great:) Even otherwise, you can always send your ideas.

Please see the links below to understand our problem setting guidelines and to see the submission form.

We look forward to seeing you setting amazing problems on CodeChef! It would be great to work with you :)

Thanks a lot in advance!
Regards,
Misha Chorniy (mgch)

A Learning Module for Beginners (Currently in Development, Feedback requested)

$
0
0

Hi fellow programmers,

We are planning to create a course for beginners. Beginners often come to the site and got overwhelmed by so many problems present on the site. Many of them often ask where to start from. So, we thought of creating a course module for them. The module will be a set of tutorials and a set of practice contests on CodeChef.

For this module, we will identify the key set of topics that a beginner should solve in order to reach a certain level. For each topic, we will have some 5 to 10 or more problems on that topic that she should solve. I have collected some set of problems for following topics (in increasing order of the difficulty). Please feel free to give any relevant feedback, suggest some problems that you think can be added or removed. Any suggestions regarding would be most welcome.

Note that currently, this module is not ready. It's still work in progress. I have marked this post a community wiki. Please feel free to edit it.

Module #0: What's competitive programming?

Competitive Programming is a mind sport where participants solve problems by writing code. The problems in question are typically logical, mathematical or algorithmic in nature. Participants must write code according to given specifications which typically includes a pre-specified time and memory limits within which a program must successfully complete execution.

Two of the most prominent competitive programming competitions are the ACM International Collegiate Programming Competition (ICPC) and the International Olympiad of Informatics (IOI) which are for univeristy and high school students respectively. The ICPC is one of the oldest, largest, hardest and most prestigious programming competitions in the world, and it is widely considered as the "Olympics" of programming.

Some other prominent programming competitons are

  • Google Code Jam
  • Facebook Hackercup
  • Topcoder Open (TCO) Algorithm
  • Yandex Algorithm

Apart from the above, regular programming competitions are conducted on various platforms across the intetnet. Some of these are

  • Codechef
  • Codeforces
  • Hackerrank
  • Topcoder
  • Hackerearth
  • Atcoder
  • CSAcademy

Getting started with CodeChef platform

Module #1: Learning A Programming Language

Check https://www.codechef.com/ioi/basics, the section "Language Constructs - C++ - 1" for basic knowledge of C++. If you want to learn basics of other languages like Java, Python, you can refer to (need to provide more links).

Just get it done :) Starting questions to do

  • FLOW001 (add two numbers)
  • FLOW002 (find reminder of a number when divided by other number)
  • TEST (one of the starting problem to solve on CodeChef)
  • INTEST (for testing whether your input/output routines are fast enough)

Basic knowledge of if/else conditions

  • FLOW010 (basic knowledge of if/else conditions)
  • FLOW014 (another if/else knowledge question)
  • LADDU (very nice implementation problem to solve)

Dealing with numbers

  • FLOW002 (find remainder of a number a % b)
  • FLOW004 (find sum of first and last digit of a number)
  • FLOW006 (find sum of digits of a number)
  • FLOW007 (given a number, reverse it)
  • FCTRL (an interesting question, must solve)

Basic knowledge of arrays

Working with strings

  • NITIKA (reading strings, and string related formatting)
  • GOODBAD (ASCII characters, lower-case and uppercase characters)
  • FLOW015 (checks basic knowledge of strings and calendar)
  • FRGTNLNG (very nice question to test input processing skills)
  • LAPIN (check whether a string is a palindrome or not)
  • CSUB (good for understanding notion of substrings)

Handling floating point numbers

Off to recursion

Provide Few More Implementation Problems:

Space and time complexity of a program

Module #2: (Basic Mathematics)

Please see https://www.codechef.com/ioi/basics, Mathematics section for very basic mathematics.

Basic Number Theory:

Module #3: Sorting algorithms

Module #4: Greedy Algorithms

Module #5: Stacks and Queues

Stack:

Queue:

  • CHFQUEUE (very nice stack and queue related problem, must do)
  • COOK82C (easy-med level problem)

Module #6: Binary Search:

Module #7: Basic Dynamic Programming

  • ALTARAY (basic dp problem)
  • SUMTRI (very nice and basic dp problem)
  • DBOY (very nice dp problem, must do)
  • XORSUB (basic 2-D dp)
  • STRMRG (a variation of standard LCS (longest common subsequence) problem, must do problem)
  • GRID (simple 2-D dp, prefix/suffix sums over a 2-D matrix, must do)
  • STRSUB (dp with binary search)

Module #8: Basic Graph Theory

Depth first search

  • FROGV (can also be done without requiring dfs by making some simple observations, in fact, dfs is overkill for it)
  • FIRESC (must do dfs problem, can also be done using union-find algorithm)
  • CHFNFRN (check whether a graph is bipartite)
  • FRIEMEET
  • DIVIDE (binary search with bipartite checking type logic)
  • MCO16104 (consider the inverse graph)
  • AUEC (existence of euler circuit in a graph)

Breadth first search

Union Find

  • BIGOF01 (very basic problem on union find, must do)
  • COLGQU (slight harder version on union find)
  • DISHOWN
  • CHFNFRN (check whether a graph is bipartite)
  • MTRWY (slight harder version on union find)
  • JABO
  • FILLMTR (very nice problem on union find, intermediate level, you may also check the video tutorials)
  • GALACTIK (a very nice union find problem)
  • PARITREE (intermediate level problem)
  • SETELE (much recommended problem)
  • MAGICSTR (recommended only for intermediate+ level)

Advanced features of languages

Check Language Constructs. It's good to learn Standard Template Library (STL) - C++ 2 section in https://www.codechef.com/ioi/basics for reading.

100% attendance laddus

$
0
0

Has anyone received the laddus for 100% participation between March '17-Feb '18?


SHKSTR - Editorial

$
0
0

Problem Link

Practice

Contest

Author:Jitender

Tester:Misha Chorniy

Editorialist:Bhuvnesh Jain

Difficulty

EASY-MEDIUM

Prerequisites

Tries, Offline querying

Problem

You a given $N$ strings and $Q$ queries. For each query, given $R$ and string $P$, you need to find the lexicographically smallest string which has the largest common prefix with $S$.

Explanation

Subtask 1: N, Q ≤ 1000

A simple brute force which checks each string from index $1$ to $R$ and stores the answer at each step will suffice. Below is a pseudo-code for it:


    def find_max_prefix_match(string a, string b):
        ans = 0
        for i in [0, len(a), len(b) - 1]:
            if a[i] == b[i]:
                ans += 1
            else:
                break
        return ans

    def solve_query(index R, string P):
        ans = ""
        prefix = 0
        for i in [1, n]:
            if find_max_prefix_match(S[i], P) > prefix:
                prefix = find_max_prefix_match(S[i], P)
                ans = S[i]
            else if find_max_prefix_match(S[i], P) == prefix:
                ans = min(ans, S[i])
        return ans

The complexity of the above approach is $O(N * Q * 10)$ in the worst case as the maximum size of the string can be at most 10.

Subtask 2: N, Q ≤ 100000

The first idea which comes whenever you see string problems deal with prefixes if using tries or hashing. In this problem too, we will use trie for solving the problem. In case you don't know about it, you can read it here.

Let us first try to understand how to find the lexicographically smallest string with largest common prefix with $P$. Assume we have the trie of all the strings build with us. We just start traversing the Trie from the root, one level at a time. Say we are at level $i$, we will try to greedily go to the node whose character matches with our current character, $P[i]$. This will help us to maximise the longest common prefix. The moment we find a mismatch, i.e. a node with current character doesn't exist, we will try to now greedily find the lexicographically find the smallest string. For this, we just keep on traversing down the left-most node in the trie till a complete work is found.

But the above approach works when $R = N$ in all queries as without it we can't identify whether the string we are traversing lies in the required range of the query or not.

There are 2 different approaches to the full solution, Online solution and Offline solution.

Author/Tester Solution: Offline Approach

The problems where we can easily solve a problem given a full array but need to query for a prefix of the array can be easily handled using offline queries. The idea is as follows:

We first sort the queries based on the index of the array given. We now build out data structure (here trie), incrementally. Say the data structure is built using all the first $i$ elements, we now answer every query which has an index as $i$ in the query.

The pseudo-code for it is below:


    queries = []
    for i in [1, q]:
        r, p = input()
        queries.push((r, p, i))
    queries.sort()

    cur_index = 0
    for (r, p, i) in queries:
        while (cur_index <= r):
            insert_element_to_ds_trie
            cur_index += 1
        ans[i] = query_from_ds_trie(S)      //parameter r is not required

    for i in [1, q]:
        print ans[i]

For more details, you can refer to the author's or tester's solution below.

Editorialist Solution: Online Solution

The idea is simple. With every node in the trie, we keep a vector of indices which it is a part of. Using this vector we can easily decide whether the string we are traversing lies within our required range or not. But before discussing the full solution, we need to be sure that this will fit into memory limits because seeing it in a naive manner seems to consume quadratic memory as each node can have a vector of length $N$.

To prove that the above-modified trie also uses linear memory in order of sum of the length of strings, we see that each index appears in any vector of a node in trie as many characters are there in the string. So, out trie just uses twice the memory that the normal trie (the one in author or tester solution) uses.

Once, the above modified Trie is built, we can answer our queries easily. Since the strings are added incrementally, we are sure that the vector containing the indices will always be in sorted order. To check whether any string at a given node lies in modified range, we can use binary search. But, we can be clever here too, as the binary search will be an overkill. Since the range we want is always a prefix of the array we can just check the first element of the vector and decide whether any string lies in the required range or not. To get a clear picture of the above, you can see the below picture of the trie build from the sample case in the problem. It also contains how the answer to different queries are arrived at.

Once, you are clear with the above idea, you can see the editorialist implementation below for help.

Feel free to share your approach, if it was somewhat different.

Time Complexity

$O(Q\log{Q} + \text{Sum of length of strings} * \text{ALPHABET})$ for offline solution

$O(\text{Sum of length of strings} * \text{ALPHABET})$ for online solution

where $\text{ALPHABET} = $ number of distinct english character (26 for this problem).

Space Complexity

$O(\text{Sum of length of strings})$

AUTHOR'S AND TESTER'S SOLUTIONS:

Author's solution can be found here.

Editorialist's solution can be found here.

somebody pls explain the gennady approach masha and minions

Parity of a permutation?

$
0
0

Someone, please explain what is the meaning of parity of permutation and how it can be helpful.

And also how can we implement it?

Can you post some question related to it practice...

Thank you.

vector of map?

$
0
0

how to create a vector of maps and how to store values in it and how to print those values??

Getting tle on my solution even when it is matching with accepted solutions.

VOTERS: I get a wrong answer, sample input works fine. Please let me know of any tricky test case I may be missing. Thanks in advance.

$
0
0
import java.util.*;
import java.lang.*;

class VOTERS{
    public static void main(String[] args){
    Scanner scanner = new Scanner(System.in);
    int N1 = scanner.nextInt();  // number of voters in first list
    int N2 = scanner.nextInt();  //  "     "   "     "  second "
    int N3 = scanner.nextInt();  //  "     "   "     "  third "

    int[] firstList = new int[N1];
    int[] secondList = new int[N2];
    int[] thirdList = new int[N3];
    for(int i=0;i<N1;i++){
        firstList[i] = scanner.nextInt();
    }
    for(int i=0;i<N2;i++){
        secondList[i] = scanner.nextInt();
    }
    for(int i=0;i<N3;i++){
        thirdList[i] = scanner.nextInt();
    }
    HashMap<Integer, Integer> countMap = new HashMap<Integer, Integer>();
    for(int i=0;i<N1;i++){
        if(countMap.containsKey(firstList[i])){
        countMap.put(firstList[i], countMap.get(firstList[i]) + 1);
        }
        else{
        countMap.put(firstList[i], 1);
        }
    }
    for(int i=0;i<N2;i++){
        if(countMap.containsKey(secondList[i])){
        countMap.put(secondList[i], countMap.get(secondList[i]) + 1);
        }
        else{
        countMap.put(secondList[i], 1);
        }
    }
    for(int i=0;i<N3;i++){
        if(countMap.containsKey(thirdList[i])){
        countMap.put(thirdList[i], countMap.get(thirdList[i]) + 1);
        }
        else{
        countMap.put(thirdList[i], 1);
        }
    }
    ArrayList<Integer> result = new ArrayList<Integer>();
    for(Map.Entry<Integer, Integer> entry : countMap.entrySet()){
        if(entry.getValue() > 1){
        result.add(entry.getKey());
        }
    }
    System.out.println(result.size());
    for(int i=0;i<result.size();i++){
        System.out.println(result.get(i));
    }
    }
}

find division of each n*n pairs in an array

$
0
0

f(n) = int(n)+1(if fractional part of n is >= 0.5) else f(n) = int(n).

In an array a of n elements . sum = 0; for(i=0; i<n; i++) { for(j=0; j<n; j++) { sum += f(a[i] / a[j]); } } 1<= n <=10^5 1<= a[i] <=10^5 Ex - for array 1 2 3 4 the value of sum is 22.


Help me out converting string into Integers in pyhthon 3.5 language

$
0
0

If a=3 and n=input().split() And there are "a" no. Of values ,means 3 values and how will we convert it into integers

TWOFL - Editorial

$
0
0

Problem Link

Practice

Contest

Author:Stacy Hong

Tester:Misha Chorniy

Editorialist:Bhuvnesh Jain

Difficulty

MEDIUM

Prerequisites

BFS, DFS, DSU, Sorting

Problem

You are given a grid with numbers written on every cell. You are required to find the largest connected component on the grid such that it contains at most 2 distinct numbers in it.

Note that editorial refers to the flowers as numbers.

Explanation

Subtask 1: N, M ≤ 100

A simple brute force which considers every pair of different numbers and performs BFS on the grid to find the connected component and their sizes is enough to pass this subtask. Below is a pseudo-code for it.


    def solve(c1, c2):
        res = 0
        for i in [1, n]:
            for j in [1, m]:
                if vis[i][j] or (a[i][j] != c1 and a[i][j] != c2):
                    continue
                # perform bfs to find size of connected component containing c1 and c2
                # update res variable with maximum value
        return res

    ans = 0
    for c1 in [1, 100]:
        for c2 in [i, 100]:
            # also handle case of one color only.
            ans = max(ans, solve(c1, c2))

The time complexity of the above approach is $O(n * m * {\text{Max(a[i][j])}}^{2})$.

Subtask 2, 3: N, Q ≤ 2000

The solution approach for last 2 subtasks is same. Just difference in implementation and constant factors can lead to passing subtask 2 only.

The full solution idea relies on the brute force solution above. Instead of doing a complete BFS on the grid every time based on the type of colour you need to consider, we store the edges containing different numbers and do BFS/DSU on it. Below are the 2 different approaches for it.

Author/Tester Solution: DSU + Sorting/HashMap

First find all connected components which have the same type of numbers. Store with each component the size of the component and the index of the component as well. This can be easily done with a BFS/DFS. Now create edges between 2 component which are adjacent to each other in the grid i.e. there exists a cell in component $1$ which is adjacent to a cell in component $2$. Store the edges in the following format:

$$\text{{Number in component 1, Number in component 2, Index of component 1, Index of component 2}}$$

To avoid doing the same computation again, store only the edges such that $\text{Number in component 1} < \text{Number in component 2}$. This will help to reduce the constant factor by 2 in your code.

Now, we traverse each edge based on the numbers they connect and perform DSU to find the maximum connected component. Below is the explanation of sample test case in the problem.

The left side image shows the different components formed after the first BFS is done. The second side image shows the result of performing DSU. So, once the BFS is done, we see that cell $(2, 1)$ containing $3$ is adjacent to cell $(1, 1)$ containing $1$, so we merge them using DSU. Again cell $(4, 1)$ containing $1$ is adjacent to cell $(4, 2)$ containing $3$ so, we merge them using DSU. The process continues as cell $(4, 3)$ containing $1$ is adjacent to $(4, 2)$ containing $3$ (which was already expanded before) and the component increases.

The only issue which needs to be taken care while implementing the above solution is resetting of DSU after every iteration. Doing it in naive manner i.e. resetting all the components to original sizes and parent as themselves will TLE even for subtask 2 as the complexity will be similar to subtask 1. Instead, we only restore the values whose parent or size changed while performing the DSU operation. This can be stored while performing the merge operation.

For more details, you can refer to the author's or tester's solution below.

The complexity of the above approach will be $O(n * m * log(n * m))$ as you will traverse each edge once. The logarithmic factor is due to sorting or using maps to store the edges. If you use hash-maps instead to store the edges, the complexity will be $O(n * m)$ but will large constant factor.

Editorialist Solution: Edge-based Graph traversal

UPDATE: This solution is slow. The author created a counter test against it. The time complexity will be $O(n^2*m^2)$ as pointed out in comments below. Even the test case provided is similar. Please refer to author's solution above for full problem. Will ask Codechef team to add that case in the practice section too for help.

Instead of forming any components or performing DSU or doing BFS like the normal way, we see simple observation in the brute force approach. If, each edge connecting adjacent cells in the grid, whether having same numbers or different numbers if traversed at most twice while determining the size, the complexity will be $O(8 * n * m)$ overall. Below is the detailed description of the idea:

First, select an edge in the grid. Find the numbers (at most 2) which will form the component. We will try to find the full component which contains this edge and make sure this component is traversed only once. For this, you start a normal BFS from each cell. You go to adjacent cell only if it is one of the 2 required numbers. While adding the node in the BFS queue, we all update the possible ways in which the edge could be traversed as part of the same component. So, cell $(3, 2)$ containing $2$ was visited from cell $(2, 2)$ containing $1$. But it could be traversed from cell $(3, 3)$ containing $1$ in future and will form the same component. So, we update all 4 directions of a cell can be visited in the same component before adding the cell in BFS queue. The BFS for a component is performed only if the edge was never traversed before in any component. The image below shows how the component is expanded in each step of BFS when the starting edge is selected as $(1, 2)$ and $(1, 3)$.

The time complexity of the above approach is $O(n^2*m^2)$ and will pass subtask 1 only.

Once, you are clear with the above idea, you can see the editorialist implementation below for help.

Feel free to share your approach, if it was somewhat different.

Time Complexity

$O(n * m)$

Space Complexity

$O(n * m)$

AUTHOR'S AND TESTER'S SOLUTIONS:

Author's solution can be found here.

Tester's solution can be found here.

Editorialist's solution can be found here. (Will TLE).

PLUSEQ - Editorial

$
0
0

Problem Link

Practice

Contest

Author:Stacy Hong

Tester:Misha Chorniy

Editorialist:Bhuvnesh Jain

Difficulty

HARD

Prerequisites

Branch and Bound, Dynamic Programming, Big Integers, Hashing, DFS/Recursion

Problem

You are given a string $S$ and integer $N$. So need to place some '+' symbols in the strings $S$ so that the value of the expression equals $N$.

Explanation

Subtask 1: N < 1000000

A simple knapsack like dynamic programming is sufficient to pass this subtask. The dp state is as follows:

$$dp[i][j] = \text{1 if first 'i' characters of S can be partitioned such that the sum is 'j' else 0}$$

A recursive pseudo-code for the above logic is given below:


    def solve(int idx, int remain):
        if idx == len(s):
            return remain == 0
        if dp[idx][remain] != -1:
            return dp[idx][remain]
        dp[idx][remain] = 0
        num = 0
        for i in [idx, len(s) - 1]:
            num = num * 10 + s[i] - '0'
            if (num > remain):
                break
            if (solve(i + 1, remain - num)):
                PLUS[i] = 1;
                return dp[idx][remain] = 1
        return dp[idx][remain];

    solve(0, N)     # N = integer value of string s in input
    for i in [0, len(s) - 1]:
        if i and PLUS[i]:
            print '+'
        print s[i]

The above code works in time complexity $O(|S| * N)$ where $|S|$ is the length of string $S$ and $N$ is the given integer. The space complexity is also same. Note that Codechef servers allow programs using such large memory (around 1G) to pass but you can you bitset or other equivalent structures to reduce the memory of your program too. See the linked solution below for subtask 1 for more details.

The solution for this subtask also exists using hashing and dynamic programming.

Subtask 2: N < |S|

Adding 2 numbers of sizes $x$ and $y$ leads to final result having size at most $max(x, y) + 1$. This is easy to prove. The size will be $max(x, y)$ if there is no carry-over in the end otherwise it will increase by 1. Extending the above logic to addition of $m$ number, we can conclude that if the numbers have lengths $x_1, x_2, \cdots, x_m$, then the length of final result is bounded by $(max(x_1 + x_2 + \cdots + x_m) + m - 1)$. You can easily prove it using induction.

Note that number of ways to partition the string $S$ into different expression is exponential. But using the above observation, you can the conclude the following fact:

Given a string $S$ and integer $N$, having the length as $n$, there is very less number way to achieve the target $N$ if $n$ is comparable to $|S|$. This is because most of the partitions will either have the maximum number in them as too low. Equivalently, if the number of partitions we put in $S$ is large, then achieving a larger target $N$ is not possible. This hints that for sufficiently large integers, the greedy technique of choosing a larger size partition and checking if the remaining part can add up to desired $N$ will run very fast in practice as the number of iterations will not be large. For example: $S = 114390211, N = 43915$

Considering greedily large size partition of $S$ such that their value is less than $N$, we have the following numbers: [11439, 14390, 43902, 39021]. (Note that the size of this selected numbers can be at most (|S| - n + 1).) Let us greedily start with $43902$. The remaining parts of $S$ are $(11, 11)$ and the required sum now is $(43915 - 43902) = 13$. Note that there are 2 ways to achieve it $(11 + 1 + 1) \text{ or } (1 + 1 + 11)$. As you can see, the number of iterations were less. The example is just a short one to make to understand how greedy recursion might behave for larger test cases.

But the other case where the integer $N$ is small but $|S|$ is very large, there can be large number of ways to achieve the desired result. For this, we have already seen that a dynamic programming solution already exists (Subtask 1). Trying the above greedy approach can be very bad in this case, a simple example being $(S = 99999999999, N = 108)$.

With some of the above ideas, we design a simple branch and bound based algorithm for the problem:


    range_tried = [0 for i in [1, len(S) - 1]]
    # Find all range in S such that their value is less than N and sort
    # them in decreasing order of their value. Let it be called "RANGES"

    def recurse(range_idx, remain):
        if remain < 0:
            return false
        if remain < LIMIT:      # LIMIT ~ 100000
            use dp based subtask_1 solution
        else:
            for i in [range_idx, len(RANGES) - 1]:
                if conflict(current_range, range_tried):
                    # If current range we are trying conflicts with one
                    # already tried in recursion before.
                    continue

                X = value of integer for RANGES[i]
                # Update range_tried
                if recurse(range_idx, remain - X):
                    return True
                # Update range_tried to old value
        return False

Note the above is a simple solution based on the initial observations. But do we need to really check for all possible ranges? Can we decide greedily at some point that given range can never result in an answer as $N$, i.e. Say we have selected some ranges, can we say that with the remaining ones we can never achieve the target $N$ without checking all possible partitions or greedily checking large number ranges.

Actually, given initial choice of our ranges, we can bound the maximum number we can achieve with the remaining ones. A simple check which ignores the digits of remaining parts of $S$ and considers all of them to be $9$ and finds the maximum value possible is a good starting point. If this value is already less than $N$, then we can simple prune our solution. Even stronger checks based on actual values of digits in string $S$ can lead to better pruning. So, the loop in the above code modifies as follows:


    for i in [range_idx, len(RANGES) - 1]:
        if conflict(current_range, range_tried):
            # If current range we are trying conflicts with one
            # already tried in recursion before.
            continue
        MAX_POSSIBLE = get_max(ranges_set)
        if MAX_POSSIBLE < N:
            # As we iterate in decreasing order of numbers, the
            # MAX_POSSIBLE can only decrease as 'i' increases
            break

        X = value of integer for RANGES[i]
        # Update range_tried
        if recurse(range_idx, remain - X):
            return True
        # Update range_tried to old value

Another thing we can do is to remove the early exit of recursion where a check is based on "remain < 0". This can be easily done by directly starting from ranges such that value of considered numbers is always less than "remain". This is again helpful as after greedily choosing a large size partition, it is possible in most case the other large size partitions should be ignored in further recursion either due to conflicts in common ranges or "remain" decreasing too fast to become less than $0$. For this, a simple binary search can help us to find the first index in "RANGES" from where we should begin our search. This is possible as we had initially stored our ranges in decreasing order of the value of integers they represent.

With the above ideas, the recursive solution based on branch and bound works quite fast in practice. A small analysis of the time complexity is as follows:

  1. $N < 100000$: Assuming we set LIMIT to this value in above pseudo-code. A dynamic programming based solution is run with complexity $O(|S| * N)$. Again to optimise this, we can use recursive version instead of iterative version. This is because will work in exactly the above complexity but in recursive solution, most of the states will be unvisited due to our initial choices of the ranges. This will significantly reduce the constant factor in your code.

  2. For most of the other cases, as $N$ becomes larger i.e. size $n$ reaches closer to $|S|$, the possible solutions reduce significantly as explained before.

A more detailed analysis of time complexity is will available soon.

Ashmelev solution (Fastest in the contest): Branch and Bound with strong bound checking

View Content

Tips for Big integer library (mostly for C++ users)

Languages like python and java already have big integer library implemented in them. But C++ users need to implement the same for their usage in this problem. A small tip is to store the numbers as groups instead of single digits. For example: $S = 123456789123456789$. Below are 2 possible ways to store $S$:

$$S = 1|2|3|4|5|6|7|8|9|1|2|3|4|5|6|7|8|9$$

$$S = 123456|789123|456789$$

This helps to perform operations on base different than 10 and reduces the constant factor of your program. Generally, the base is chosen as ${10}^{9}$ so that all possible operations like $(+, -, * , /)$ fit inside the datatypes provided by the language. You can see setter's library for example.

Time Complexity

To be described in detail later.

Space Complexity

To be described in detail later.

Solution Links

The solution for subtask 1 can be found here

Setter's solution can be found here

Ashmelev's solution can be found here

[Request] Should we allow Team Participation in regular contest??

$
0
0

[Open For Discussion] -

Today I was going through Somewhat suspicious coderkgcstar and kutengine competing in teams? . I'm not interested in raising issue again.

Since CodeChef's Code Of Conduct Says -
You may try to solve a problem as a team, but then make sure that there is only one submission made for a discussed solution in a contest. Submitting the same solution (even algorithm) by the different members of the team or a discussion group is not fair and will be considered as plagiarism.

Instead If we also have team registration option in long, cook and lunchtime. Due credit can be given to all members. If few individual's register/participate as a team. Then if a individual tries to submit from his personal account (accidentally), pop up can be shown to him that you are not allowed. This can save team from plagiarism hammer.
This will also help teams for preparations for ACM-ICPC. Ultimate objective of CodeChef

My point is If it is allowed then why there is no way to register/participate as team ??

And I cannot find any button for creating a team. Only method I found I look for upcoming team contest. And register for that contest after creating team. Does there exist any method to register team other than this.

P.S. - Contest like IOITC181 should have a team participation option.

FUNFES-Editorial

$
0
0

PROBLEM LINK:

Practice

Author:Arjun Bharat
Tester:Arjun Bharat
Editorialist:Arjun Bharat

DIFFICULTY:

EASY-MEDIUM

PREREQUISITES:

Math, modular exponentiation

PROBLEM:

Given the functional equation f(x+1)=kf(x)+g(x), g(x+1)=kg(x)+f(x), f(0)=2 and g(0)=0, the task is to find the value of f(n) modulo 1000000007, where n and k are program inputs.

QUICK EXPLANATION:

This is achieved by first solving the equations to obtain: f(x)= 2x, if(k=1)f(x)= (k+1)x + (k-1)x, for k>1. Then we compute the remainder using fast modular exponentiation which is best suited for the given constraints.

EXPLANATION:

One may either add or subtract the two equations and obtain these following equations: f(x+1)-g(x-1)=(k-1)(f(x)-g(x)),f(x+1)+g(x+1)=(k+1)(f(x)+g(x)) Thus defining new functions h(x)=f(x)+g(x) and p(x)=f(x)-g(x), we have p(x)=2*(k-1)x, h(x)=2*(k+1)x. Substituting any one of them back will yield f(x+1)=(k+1)f(x)-(k-1)x, and thus by superposition of the homogeneous and particular solutions to the recursive relation, set f(x)=a(k+1)x + b(k-1)x</sup***,> + (k-1)x. Now we proceed to obtain the remainder.
Notice that using a linear recurrence, ans(n)=(k * ans(n-1))%M is O(n) and will not pass in under one second.
We proceed to use fast modular exponentiation. A brief snippet coded in C++ is highlighted below:
long long fn(long long n,long long k)
{
if(n==0)
return 1;
else if(n==1)
return k;
else if(n%2==0)
{
long long y = fn(n/2,k);
return ((y%M)(y%M))%M;
}
else
{
long long z= fn(n/2,k);
return ((y%M)
(y%M)*(k))%M;
}
}
long long ans = fn(n,k+1)+fn(n,k-1);
ans%=M;//M=10^9+7
//This code works even when k=0, as the second call returns 0. This is O(lg n), a marked improvement.

ALTERNATIVE SOLUTION:

The trivial solution is to use a linear recurrence as described earlier, which is not suitable based on program constraints.
Manually computing and storing f(x) and g(x) values, with or without modulo is not advisable due to their large magnitudes, and the linear time complexity involved therein.

AUTHOR'S AND TESTER'S SOLUTIONS:

Author's solution can be found here: jdoodle.com/a/wPF

RELATED PROBLEMS:

TOPTWO

Viewing all 40121 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>