Java 黑客与警察及其问题

Java 黑客与警察及其问题,java,algorithm,matrix,Java,Algorithm,Matrix,我正在努力解决HackerEarth网站上的警察和他们的问题。我能够降低时间复杂度,但有三个测试用例失败。解决方案中似乎有一个错误,导致了一个小的不匹配。几个星期以来,我一直在努力寻找错误。下面是问题陈述和我的代码 警察和小偷问题陈述: import java.io.*; import java.util.*; public class TestClass { public static void main(String[] args) throws IOException {

我正在努力解决HackerEarth网站上的警察和他们的问题。我能够降低时间复杂度,但有三个测试用例失败。解决方案中似乎有一个错误,导致了一个小的不匹配。几个星期以来,我一直在努力寻找错误。下面是问题陈述和我的代码

警察和小偷问题陈述:

import java.io.*;
import java.util.*;

public class TestClass {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        PrintWriter wr = new PrintWriter(System.out);
        int T = Integer.parseInt(br.readLine().trim());
        for(int t_i=0; t_i<T; t_i++)
        {
            String[] line = br.readLine().split(" ");
            int N = Integer.parseInt(line[0]);
            int K = Integer.parseInt(line[1]);
            char[][] A = new char[N][N];
            for(int i_A=0; i_A<N; i_A++)
            {
                String[] arr_A = br.readLine().split(" ");
                for(int j_A=0; j_A<arr_A.length; j_A++)
                {
                    A[i_A][j_A] = arr_A[j_A].charAt(0);
                }
            }

            int out_ = solution(A, K);
            System.out.println(out_);
            System.out.println("");
        }

        wr.close();
        br.close();
    }
    static int solution(char[][] A, int K){
        int count = 0;
        for(int i=0;i<A.length;i++){
            for(int j=0;j<A[i].length;j++){
                if(A[i][j]=='P'){
                    boolean thiefCaptured = false;
                    int x;
                    if(j-K >0){
                        x = j-K;
                    }else {
                        x = 0;
                    }
                    for(;x<j;x++) {
                        if (A[i][x] == 'T') {
                            A[i][x] = 'X';
                            A[i][j] = 'X';
                            count++;
                            thiefCaptured = true;
                            break;
                        }
                    }
                    int y;
                    if(j+K < A[i].length){
                        y = j+K;
                    }else{
                        y = A[i].length - 1;
                    }
                    for(;(y>j) && (thiefCaptured == false);y--){
                        if(A[i][y]=='T'){
                            A[i][y] = 'X';
                            A[i][j] = 'X';
                            count++;
                            break;
                        }
                    }
                }
            }
        }
        return count;
    }
}
将为您提供一个具有以下规格的网格:

  • 网格中的每个单元包含一名警察或一名小偷
  • 只有当小偷和警察在同一排时,警察才能抓住他们
  • 每个警察只能抓一个小偷
  • 一个警察抓不到一个距离警察超过K个单位的小偷。 编写一个程序,找出网格中可以抓到的最大窃贼数量
输入格式

  • 第一行:T(测试用例数)

    对于每个测试用例

    • 第一行包含两个空格分隔的整数N和K
    • 接下来的N行包含N个空格分隔的字符(表示网格中的每个单元格)
输出格式

对于每个测试用例,打印网格中可以捕获的最大窃贼数量

我的代码:

import java.io.*;
import java.util.*;

public class TestClass {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        PrintWriter wr = new PrintWriter(System.out);
        int T = Integer.parseInt(br.readLine().trim());
        for(int t_i=0; t_i<T; t_i++)
        {
            String[] line = br.readLine().split(" ");
            int N = Integer.parseInt(line[0]);
            int K = Integer.parseInt(line[1]);
            char[][] A = new char[N][N];
            for(int i_A=0; i_A<N; i_A++)
            {
                String[] arr_A = br.readLine().split(" ");
                for(int j_A=0; j_A<arr_A.length; j_A++)
                {
                    A[i_A][j_A] = arr_A[j_A].charAt(0);
                }
            }

            int out_ = solution(A, K);
            System.out.println(out_);
            System.out.println("");
        }

        wr.close();
        br.close();
    }
    static int solution(char[][] A, int K){
        int count = 0;
        for(int i=0;i<A.length;i++){
            for(int j=0;j<A[i].length;j++){
                if(A[i][j]=='P'){
                    boolean thiefCaptured = false;
                    int x;
                    if(j-K >0){
                        x = j-K;
                    }else {
                        x = 0;
                    }
                    for(;x<j;x++) {
                        if (A[i][x] == 'T') {
                            A[i][x] = 'X';
                            A[i][j] = 'X';
                            count++;
                            thiefCaptured = true;
                            break;
                        }
                    }
                    int y;
                    if(j+K < A[i].length){
                        y = j+K;
                    }else{
                        y = A[i].length - 1;
                    }
                    for(;(y>j) && (thiefCaptured == false);y--){
                        if(A[i][y]=='T'){
                            A[i][y] = 'X';
                            A[i][j] = 'X';
                            count++;
                            break;
                        }
                    }
                }
            }
        }
        return count;
    }
}
预期输出 113

实际产出 112

你们能帮我找出哪里出了问题吗?事实上,我花了几个星期的时间试图找出解决方案,但没有取得进展。我知道对于同一个问题有不同的解决方案。但问题是我想找出我逻辑中的问题或漏洞。请帮帮我


链接:

我添加了一个逻辑来修复@OleV.V指出的错误。增加的逻辑是,如果两个小偷连续出现在警察面前,首先抓住最近的一个现在失败的测试用例通过了,但之前通过的测试用例中有三个由于时间复杂性问题超时。下面是解决@OleV.V指出的错误后的代码。现在,我们必须在时间复杂性方面进行修正:(

import java.io.*;
导入java.util.*;
公共类TestClass{
公共静态void main(字符串[]args)引发IOException{
BufferedReader br=新的BufferedReader(新的InputStreamReader(System.in));
PrintWriter wr=新的PrintWriter(系统输出);
int T=Integer.parseInt(br.readLine().trim());

对于(int t_i=0;t_i您的bug显示在
i
11行(如果您自然计数/1,则为第12行)

这一排有8个小偷。他们都可以被抓住。在下面的一行中,
+
表示一个警察或女警察成功抓住了一个小偷,而
-
表示一个也抓不到

+ T - + T + T + T + T + T T T + + -
(第一个小偷可能会被左边或右边的警察抓住,这与计数没有关系。至于谁抓住了前两个小偷,可能会有更多的变化。)

你的程序只“捕获”了8个窃贼中的7个。在这一行之前,你的计数是68,我相信这是正确的。在这一行之后,你的计数是75,应该是76

在这一行中,前5个小偷被抓获了。现在索引11处的警察做了什么?左边的小偷已经被抓获了。右边是三个小偷。你的第二个最里面的循环从
y
=
j+K
=11+2=13向下倒计时,所以在索引13处抓到小偷,而在索引12处抓到小偷没问题。下一个警官在指数15。当K为2时,他/她无法抓住指数12的小偷,距离太远了

编辑:我的解决方案想法。既然你发布了你的解决方案,我想我可以发布我的解决方案,而不会破坏任何东西。我的想法是让每个小偷从左到右搜索一名能够抓到小偷的警察。我将在上次搜索结束的地方开始搜索。这确保每个警察只抓到一名警察小偷

    char[] row = { 'P', 'T', 'P', 'P', 'T', 'P', 'T', 'P', 'T',
            'P', 'T', 'P', 'T', 'T', 'T', 'P', 'P', 'P' };
    int k = 2; // The uppercase K from the problem

    int count = 0;
    // Index from where to search for the next police officer to catch a thief
    int pix = 0;
    for (int ix = 0; ix < row.length; ix++) {
        if (row[ix] == 'T') {
            if (pix < ix - k) {
                pix = ix - k;
            }
            int searchLimit = Math.min(row.length, ix + k + 1);
            while (pix < searchLimit && row[pix] != 'P') {
                pix++;
            }
            if (pix < searchLimit) { // Found
                count++;
                pix++;
            }
        }
    }

    System.out.println(count);
char[]行={'P','T','P','P','P','T','P','T','P','T',',
‘P’、‘T’、‘P’、‘T’、‘T’、‘P’、‘P’、‘P’};
int k=2;//问题的大写字母k
整数计数=0;
//从何处搜索下一个警察抓小偷的索引
int-pix=0;
for(int ix=0;ix
输出:

八,

我没有使用任何辅助数据结构,也没有修改输入数组。我相信这个算法是有效的(我没有在hackerearth上尝试过)

这个问题在警察和小偷身上是对称的,所以一个人可能会反过来做,因为每个警察都在寻找要抓住的小偷,这将起到同样的作用

如果
Math.min()
调用感觉异常,请使用
?:
三元运算符或
If
-
else
构造


PS也许在HackerAth上,p代表警官,H代表黑客,问有多少黑客没有被警察抓到就逃走了会更合适。开个玩笑。

我从GeekForgeks网站上得到了一个解决方案,它使用了一个非常简单的逻辑,基于警察和小偷的索引。我想,就这么简单!!!?好吧,这就是世界的运作方式。无论如何,这是解决上述问题的最佳方案

import java.io.*;
import java.util.*;

public class TestClass {

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        PrintWriter wr = new PrintWriter(System.out);
        int T = Integer.parseInt(br.readLine().trim());
        for(int t_i=0; t_i<T; t_i++)
        {
            String[] line = br.readLine().split(" ");
            int N = Integer.parseInt(line[0]);
            int K = Integer.parseInt(line[1]);
            char[][] A = new char[N][N];
            for(int i_A=0; i_A<N; i_A++)
            {
                String[] arr_A = br.readLine().split(" ");
                for(int j_A=0; j_A<arr_A.length; j_A++)
                {
                    A[i_A][j_A] = arr_A[j_A].charAt(0);
                }
            }

            int out_ = solution(A, K);
            System.out.println(out_);
            System.out.println("");
        }

        wr.close();
        br.close();
    }
    static int solution(char[][] arr, int K){
        int count = 0;
        for(int i=0;i<arr.length;i++){
                ArrayList<Integer> thi = new ArrayList<>();
                ArrayList<Integer> pol = new ArrayList<>();
                for (int s = 0; s < arr[i].length; s++) {
                    if (arr[i][s] == 'P')
                        pol.add(s);
                    else if (arr[i][s] == 'T')
                        thi.add(s);
                }
                int l = 0, r = 0;
                while (l < thi.size() && r < pol.size()) {
                    if (Math.abs(thi.get(l) - pol.get(r)) <= K) {
                        count++;
                        l++;
                        r++;
                    }
                    else if (thi.get(l) < pol.get(r))
                        l++;
                    else
                        r++;
                }
        }
        return count;
    }
}
import java.io.*;
导入java.util.*;
公共类TestClass{
公众的
    char[] row = { 'P', 'T', 'P', 'P', 'T', 'P', 'T', 'P', 'T',
            'P', 'T', 'P', 'T', 'T', 'T', 'P', 'P', 'P' };
    int k = 2; // The uppercase K from the problem

    int count = 0;
    // Index from where to search for the next police officer to catch a thief
    int pix = 0;
    for (int ix = 0; ix < row.length; ix++) {
        if (row[ix] == 'T') {
            if (pix < ix - k) {
                pix = ix - k;
            }
            int searchLimit = Math.min(row.length, ix + k + 1);
            while (pix < searchLimit && row[pix] != 'P') {
                pix++;
            }
            if (pix < searchLimit) { // Found
                count++;
                pix++;
            }
        }
    }

    System.out.println(count);
import java.io.*;
import java.util.*;

public class TestClass {

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        PrintWriter wr = new PrintWriter(System.out);
        int T = Integer.parseInt(br.readLine().trim());
        for(int t_i=0; t_i<T; t_i++)
        {
            String[] line = br.readLine().split(" ");
            int N = Integer.parseInt(line[0]);
            int K = Integer.parseInt(line[1]);
            char[][] A = new char[N][N];
            for(int i_A=0; i_A<N; i_A++)
            {
                String[] arr_A = br.readLine().split(" ");
                for(int j_A=0; j_A<arr_A.length; j_A++)
                {
                    A[i_A][j_A] = arr_A[j_A].charAt(0);
                }
            }

            int out_ = solution(A, K);
            System.out.println(out_);
            System.out.println("");
        }

        wr.close();
        br.close();
    }
    static int solution(char[][] arr, int K){
        int count = 0;
        for(int i=0;i<arr.length;i++){
                ArrayList<Integer> thi = new ArrayList<>();
                ArrayList<Integer> pol = new ArrayList<>();
                for (int s = 0; s < arr[i].length; s++) {
                    if (arr[i][s] == 'P')
                        pol.add(s);
                    else if (arr[i][s] == 'T')
                        thi.add(s);
                }
                int l = 0, r = 0;
                while (l < thi.size() && r < pol.size()) {
                    if (Math.abs(thi.get(l) - pol.get(r)) <= K) {
                        count++;
                        l++;
                        r++;
                    }
                    else if (thi.get(l) < pol.get(r))
                        l++;
                    else
                        r++;
                }
        }
        return count;
    }
}