45 lines Java with DP and explaination faster than (100%, 100%)
dp[i][j][0] means the minimum step to move to (i,j) and the snake is horizontal now.\n dp[i][j][1] means the minimum step to move to (i,j) and the snake is vert
* dp[i][j][0] means the minimum step to move to (i,j) and the snake is horizontal now.\n* dp[i][j][1] means the minimum step to move to (i,j) and the snake is vertical now.\n\nstate transfer function: \n* dp[i][j][0] = Min(dp[i-1][j][0], dp[i][j-1][0], dp[i+1][j-1][1]) + 1 // down, right, counterclockwise\n* dp[i][j][1] = Min(dp[i-1][j][1], dp[i][j-1][1], dp[i-1][j+1][0]) + 1 // down, right, clockwise\n\nPlease note each operation needs to check some limitations carefully.\n\n```\nclass Solution {\n    public int minimumMoves(int[][] grid) {\n        int n = grid.length;\n        int[][][] dp = new int[n][n][2];\n        // initial\n        for(int i=0; i<n; i++){\n            for(int j=0; j<n; j++){\n                dp[i][j][0] = dp[i][j][1] = Integer.MAX_VALUE;\n            }\n        }\n        // base case\n        dp[0][1][0] = 0;\n        if(grid[1][0] == 0 && grid[1][1] == 0) dp[1][0][1] = 1;\n        for(int i=2; i<n; i++){\n            if(grid[0][i] == 0 && dp[0][i-1][0] != Integer.MAX_VALUE) dp[0][i][0] = dp[0][i-1][0] + 1;\n            if(grid[i][0] == 0 && dp[i-1][0][1] != Integer.MAX_VALUE) dp[i][0][1] = dp[i-1][0][1] + 1;\n        }\n        \n        // start dp, k is the length of diagonal line from bottom left to upper right\n        for(int k=2; k<=2*n-2; k++){\n            for(int j=k<=n-1? 1: k-n+1; j<n && j<k; j++){\n                int i = k-j;\n                // when the snake is horizontal with head at (i,j)\n                if(grid[i][j] == 0 && grid[i][j-1] == 0){\n                    dp[i][j][0] = Math.min(dp[i][j-1][0], dp[i-1][j][0]);\n                    if(i<n-1 && grid[i+1][j] == 0) dp[i][j][0] = Math.min(dp[i][j][0], dp[i+1][j-1][1]);\n                    // If it\'s possible to move to (i,j) with horizontal body\n                    if(dp[i][j][0] != Integer.MAX_VALUE){\n                        dp[i][j][0] += 1;\n                        if(i<n-1 && grid[i+1][j] == 0 && grid[i+1][j-1] == 0){\n                            dp[i+1][j-1][1] = Math.min(dp[i][j][0]+1, dp[i+1][j-1][1]);\n                        }\n                    }\n                }\n                // when the snake is vertical with head at (i,j)\n                if(grid[i][j] == 0 && grid[i-1][j] == 0){\n                    dp[i][j][1] = Math.min(dp[i-1][j][1], dp[i][j-1][1]);\n                    if(j<n-1 && grid[i][j+1] == 0) dp[i][j][1] = Math.min(dp[i][j][1], dp[i-1][j+1][0]);\n                    // If it\'s possible to move to (i,j) with vertical body\n                    if(dp[i][j][1] != Integer.MAX_VALUE){\n                        dp[i][j][1] += 1;\n                        if(j<n-1 && grid[i][j+1] == 0 && grid[i-1][j+1] == 0){\n                            dp[i-1][j+1][0] = Math.min(dp[i][j][1]+1, dp[i-1][j+1][0]);\n                        }\n                    }\n                }\n            }\n        }\n\n        return dp[n-1][n-1][0] == Integer.MAX_VALUE? -1: dp[n-1][n-1][0];\n    }\n}\n```
[]