Sumanto's blog

By Sumanto, 12 months ago, In English

https://cses.fi/problemset/task/1625 I am applying staright forward DFS to the problem but it's getting Time Limit Exceeded. How to optimise the code. I checked out William Lin's Livestream but did'nt get his approach to the problem

 
 
 
 
  • Vote: I like it
  • +5
  • Vote: I do not like it

»
11 months ago, # |
  Vote: I like it 0 Vote: I do not like it

https://cses.fi/book/book.pdf page 52 (the printed page number) or 62 (the pdf page number)

  • »
    »
    11 months ago, # ^ |
      Vote: I like it 0 Vote: I do not like it

    thanks

  • »
    »
    10 months ago, # ^ |
      Vote: I like it 0 Vote: I do not like it

    i understood the optimisations, but can you explain the runtime mathematically? the explanations there looks more experimental.

»
10 months ago, # |
  Vote: I like it 0 Vote: I do not like it

Can anyone with a sharp eye help me please? I basically tried “to go by the the book”, and do the pruning of the T-shaped wall hits, — just as @tmwilliamlin168 does for this problem in his epic 11-hour stream.

Still, however, I'm getting 30+ seconds on the all-question-marks 88418 paths case. What am I missing? I tried to code it up in a clean way, so you probably won't have any trouble following the logic.

Thanks!

The code
  • »
    »
    10 months ago, # ^ |
    Rev. 2   Vote: I like it 0 Vote: I do not like it

    I've shaved off about 50% of time by removing all that pairs instantiations. Still not good enough. 16 seconds on the 88418 paths case. Help!

    Version 2
  • »
    »
    10 months ago, # ^ |
    Rev. 2   Vote: I like it 0 Vote: I do not like it

    So, seems like, the constraints are really tight, and the constant factor caused by all the nice code factorizations was simply killing it. After I unrolled all the DRY-ness, and uglified the code to the point listed below, it got accepted.

    UPD: Ah, btw, the absolute numbers in seconds I quoted above are not quite representative, as I ran the code with memory sanitization, and all the optimizations disabled. So, it should be, like, 7 times faster, when run by the OJ.

    Version 3
    • »
      »
      »
      4 months ago, # ^ |
        Vote: I like it 0 Vote: I do not like it

      This is my simple code within 1s(https://ideone.com/r9lZ5z)

    • »
      »
      »
      2 months ago, # ^ |
        Vote: I like it 0 Vote: I do not like it

      I have also tried many optimization but still getting TLE after spending too much time on the problem. If could you please suggest me some improvements

      Code
      • »
        »
        »
        »
        2 months ago, # ^ |
          Vote: I like it 0 Vote: I do not like it

        It doesn't seem like the code is pruning the impossible paths early enough. Am I right, that it recurs until it runs out of moves, or hits the end point?

        Did you read “Pruning the search” section starting from the page 51 of the CSES book?

        • »
          »
          »
          »
          »
          2 months ago, # ^ |
            Vote: I like it 0 Vote: I do not like it

          the moveTo method is doing the pruning part as mentioned in the book. whenever I reach the boundary I avoid atleast one direction of movement.

          Other optimization which I have done is the generalized part as mentioned in the book. Though I am not sure the way I have implemented is correct or not.

          • »
            »
            »
            »
            »
            »
            2 months ago, # ^ |
              Vote: I like it 0 Vote: I do not like it

            Ah! I see, indeed. So, right, there's pruning in case of hitting a wall. For me it was not enough. It was also necessary to prune when hitting an already visited cell, and forming a T-shape, not just a T-shape on the boundary.

            x--x
            |  |
            x->|
               x--
            
            • »
              »
              »
              »
              »
              »
              »
              2 months ago, # ^ |
                Vote: I like it 0 Vote: I do not like it

              I have handled that too, by using the concept of direction. For each cell I have stored the direction from which I have arrived that cell, and in case (the one which you have mentioned about) suppose I reach cell (i, j) and I notice that cell (i, j+1) is already visited so in that case I have only two directions to move, out of which only one direction is good. I tried some examples and deduced that the direction which is not favourable is the direction specified by me in proceed() method [which is the direction of arrival at that cell]. so if up direction is stored in direction[i, j+1] then I will avoid going upwards from cell (i, j). I think that's what you mean by the T-shape. I am not sure if my way of handling is inappropriate or it is just time consuming.

              • »
                »
                »
                »
                »
                »
                »
                »
                2 months ago, # ^ |
                Rev. 3   Vote: I like it 0 Vote: I do not like it

                Oh… Ok.

                Could it be that in such a case — $$$(i, j + 1)$$$ visited, you shouldn't even consider visiting the $$$(i, j)$$$?

                Here's my code handling that exact situation:

                if ((pattern[i] == '?' || pattern[i] == 'R') &&
                    is_possible(covered, ro, co + 1)) { // R
                    bool locked = !is_possible(covered, ro, co + 2) &&
                                  is_possible(covered, ro - 1, co + 1) &&
                                  is_possible(covered, ro + 1, co + 1);
                
                    if (!locked) {
                        covered[ro][co + 1] = true;
                        recur(pattern, ans, covered, i + 1, ro, co + 1);
                        covered[ro][co + 1] = false;
                    }
                }
                

                So, if $$$(i, j + 1)$$$ is visited, and the path would form a T-shape, I don't even go from $$$(i, j - 1)$$$ to $$$(i, j)$$$. The $$$locked$$$ boolean here means “there would be a T-shape”.

                • »
                  »
                  »
                  »
                  »
                  »
                  »
                  »
                  »
                  2 months ago, # ^ |
                    Vote: I like it 0 Vote: I do not like it

                  thought of something like that but got confused regarding the correctness. Thanks by the way!!

                • »
                  »
                  »
                  »
                  »
                  »
                  »
                  »
                  »
                  2 months ago, # ^ |
                    Vote: I like it 0 Vote: I do not like it

                  one update!! I did one more optimization which is if somehow I have created an Island of zeroes surrounded by ones in the matrix then again the answer is not possible. For that I am doing an explicit dfs for checking the number of connected components with zeroes if such number is greater then one then the answer is not possible in such case and we need to do backtrack rather than moving on. But still I am getting TLE on some cases.

                  updated code (10/20 testcases passed)
        • »
          »
          »
          »
          »
          11 days ago, # ^ |
            Vote: I like it 0 Vote: I do not like it

          Nope! actually these optimizations came from discussion between 1 of friends. We are coding partners. But i checked in the book i'm you mentioned and i'm glad to know that we arrived at same solution. It's just our good luck!

»
6 weeks ago, # |
Rev. 2   Vote: I like it 0 Vote: I do not like it

Hello everyone, I also tried implementing it but in 4-5 cases it gives TLE, can someone please tell me what optimizations I am missing.

My code
  • »
    »
    6 weeks ago, # ^ |
    Rev. 12   Vote: I like it 0 Vote: I do not like it

    whenever you post a code/solution on codeforces you should add it inside spoiler so that it is easier for other user to read. you can use spoiler like this

    like this
    • »
      »
      »
      6 weeks ago, # ^ |
        Vote: I like it 0 Vote: I do not like it

      Oh, I'm sorry, I didn't knowthat. I will edit it. Thank you

    • »
      »
      »
      6 weeks ago, # ^ |
        Vote: I like it 0 Vote: I do not like it

      Also, can you suggest to me some optimization that I need to do in my code to make it pass all the test cases?

  • »
    »
    6 weeks ago, # ^ |
      Vote: I like it 0 Vote: I do not like it

    Great comments lol

»
6 weeks ago, # |
  Vote: I like it 0 Vote: I do not like it

A normal dfs/backtracking approach would take exponential time. So in such type of questions we use dfs with pruning, we prune the unnecessary states such that they are not explored further. So a normal dfs would have 4^48 calls (at max) which is astronomical but with dfs and pruning method it would take us nearly 1s to process some million recursive calls