rohantrix's blog

By rohantrix, history, 3 years ago, In English

[SOLVED] Both the codes in Java and Python TLE on CSES for same test cases (7-10). Please help me resolve this issue.

Java: [WORKING NOW]

    static int endi, endj;
 
    static void solve() throws IOException{
        StringTokenizer st;
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter output = new BufferedWriter(new OutputStreamWriter(System.out));
        st = new StringTokenizer(br.readLine());
        int n = Integer.parseInt(st.nextToken());
        int m = Integer.parseInt(st.nextToken());
        char mat[][] = new char[n][m];
        char dir[][] = new char[n][m]; 
        fill2D(dir, '#');
        int si = 0, sj = 0;
        for (int i = 0; i < n; i++) {
            st = new StringTokenizer(br.readLine());
            mat[i] = st.nextToken().toCharArray();
            for (int j = 0; j < m; j++) {
                if (mat[i][j] == 'A') {
                    si = i;
                    sj = j;
                } else if (mat[i][j] == 'B') {
                    endi = i;
                    endj = j;
                }
            }
            
        }
        
        boolean f = false;
        ArrayDeque<int[]> q = new ArrayDeque<>();
        q.offerLast(new int[]{si, sj});
        while (!q.isEmpty()) {
            int[] tmp = q.pollFirst();
            // System.out.println(tmp);
            if (tmp[0] == endi && tmp[1] == endj) {
                f = true;
                break;
            }
            
 
            int nx, ny;
            // Left
 
            nx = tmp[0];
            ny = tmp[1] - 1;
            if (!(nx < 0 || nx >= n || ny < 0 || ny >= m || mat[nx][ny] == '#')) {
                q.offerLast(new int[]{nx,ny});
                dir[nx][ny] = 'L';
                mat[nx][ny] = '#';
 
            }
 
            // Right
 
            nx = tmp[0];
            ny = tmp[1] + 1;
            if (!(nx < 0 || nx >= n || ny < 0 || ny >= m || mat[nx][ny] == '#')) {
                q.offerLast(new int[]{nx,ny});
                dir[nx][ny] = 'R';
                mat[nx][ny] = '#';
            }
 
            // Up
            nx = tmp[0] - 1;
            ny = tmp[1];
            if (!(nx < 0 || nx >= n || ny < 0 || ny >= m || mat[nx][ny] == '#')) {
                q.offerLast(new int[]{nx,ny});
                dir[nx][ny] = 'U';
                mat[nx][ny] = '#';
            }
            // Down
            nx = tmp[0] + 1;
            ny = tmp[1];
            if (!(nx < 0 || nx >= n || ny < 0 || ny >= m || mat[nx][ny] == '#')) {
                q.offerLast(new int[]{nx,ny});
                dir[nx][ny] = 'D';
                mat[nx][ny] = '#';
            }
            // System.out.println(q);
        }
        StringBuilder s = new StringBuilder();
        if (!f)
        System.out.println("NO");
        else {
            int nx = endi, ny = endj;
            while(nx!=si || ny!=sj)
            {
                s.append(dir[nx][ny]);
                switch(dir[nx][ny])
                {
                    case 'L':{ny++;break;}
                    case 'R':{ny--;break;}
                    case 'U':{nx++;break;}
                    case 'D':{nx--;break;}
                }
            }
            s.reverse();
            output.write("YES\n");
            output.write(s.length() + "\n");
            output.write(s.toString());
        }
        output.flush();

 
    }
  • Vote: I like it
  • 0
  • Vote: I do not like it

| Write comment?
»
3 years ago, # |
  Vote: I like it +8 Vote: I do not like it

The time limit on cses is little tight, only cpp is safe to use.

»
3 years ago, # |
  Vote: I like it 0 Vote: I do not like it

Using Python on problems like this can be very tricky. Unlike in C++, in Python you really have to write code in a way that doesn't run slow in Python. You can see my submission here (https://cses.fi/problemset/hack/1193/entry/2793845/). It runs in 0.24 s. The main difference between our codes is how the BFS is coded:

P = [-2 if c == '#' else -1 for row in mat for c in row]
Apos = si + sj * m
P[Apos] = Apos
bfs = [Apos]
for pos in bfs:
    ypos, xpos = divmod(pos, m)

    pos2 = pos + 1
    if xpos + 1 < m and P[pos2] == -1:
        P[pos2] = pos
        bfs.append(pos2)
    
    pos2 = pos - 1
    if xpos and P[pos2] == -1:
        P[pos2] = pos
        bfs.append(pos2)
    
    pos2 = pos + m
    if ypos + 1 < n and P[pos2] == -1:
        P[pos2] = pos
        bfs.append(pos2)
    
    pos2 = pos - m
    if ypos and P[pos2] == -1:
        P[pos2] = pos
        bfs.append(pos2)
»
11 months ago, # |
  Vote: I like it 0 Vote: I do not like it

@pajenegod is correct. I've seen this before with some USACO problems too. Seems like with Python queue is slow if element is tuple or anything but singleton. Converting from (r, c) to (r * cols + c) is the way.