In 2018, the 9th Blue Bridge Cup Java Programming Undergraduate Group B Final Finished Toys (Programming Topics)

2018 Ninth Blue Bridge Cup Java Programming Undergraduate Group B Final Individual Problem Solution Summary:

https://blog.csdn.net/daixinliangwyx/article/details/90258768

 

Question 3

Title: Organize Toys

Xiao Ming has a set of toys that contains NxM parts in total. The parts are placed in a toy box containing NxM cells, each of which contains exactly one part.  

Each part is marked with an integer from 0 to 9, and there may be multiple parts marked with the same integer.  

Xiao Ming has special requirements for the placement of toys: parts marked with the same integer must be placed together to form a rectangular shape.

The following placement is satisfactory:

00022
00033
44444  

12244
12244
12233

01234
56789

The following placements do not meet the requirements:

11122
11122
33311

111111
122221
122221
111111

11122
11113
33333

Give a placement method, please judge whether it meets Xiao Ming's requirements.

Input
----
The input contains multiple sets of data.  
The first line contains an integer T, representing the number of data groups. (1 <= T <= 10) 
contains T groups of data.  
The first row of each set of data contains two integers N and M. (1 <= N, M <= 10)  
The following matrix contains N rows and M columns, representing the placement method.  

Output
---
For each set of data, output YES or NO to indicate whether it meets Xiaoming's requirements.  

【Sample input】
3  
3 5  
00022
00033
44444  
3 5  
11122
11122
33311
2 5  
01234
56789

【Example output】
YES
NO
YES


Resource convention:
peak memory consumption (including virtual machine) < 256M
CPU consumption < 1000ms


Please output strictly according to the requirements, and do not superficially print superfluous content like: "Please enter...".

All code is placed in the same source file, after debugging, copy and submit the source code.
Don't use the package statement. Do not use features of jdk1.7 and above.
The name of the main class must be: Main, otherwise it will be processed as invalid code.


Solution: It can be solved by using union search. First number each position of the entire matrix, and then use a set to record how many kinds of numbers there are in the entire matrix, then check the matrix together, and use another set to count the number of connections in the matrix, but only by judging the number of connected blocks and the type of numbers Whether it is the same to get whether the conditions are met is not acceptable, for example:

111111
122221
122221
111111

The number of connected blocks in this matrix is ​​equal to the number of types, but this matrix is ​​not eligible because the number 1 is not placed together to form a rectangle (the middle is empty).

Therefore, we also need to judge whether each connecting block is a solid matrix, then we can judge by the area. If each connecting block is a solid matrix, the sum of the areas of all connecting blocks must be equal to the area of ​​the entire matrix. As for the area of ​​the solid rectangle of the connected block, you can maintain the x and y coordinate ranges in the connected block when merging the set (open the structure array, each structure corresponds to a point on the matrix, and then update the stored value in the block. The minimum x coordinate, the minimum y coordinate, the maximum x coordinate, and the maximum y coordinate are in the root node structure), and then the coordinate difference is obtained through these two coordinate ranges to calculate the minimum area of ​​the connected block to form a solid rectangular block. If the number of the last connected blocks and the type of numbers are the same and the sum of the minimum areas of all connected blocks to form a solid rectangle is equal to the area of ​​the entire matrix, then it is YES, otherwise it is NO. (If some connected blocks are not solid rectangles, the calculated area will be larger than the entire matrix)

Code:

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.math.BigInteger;
import java.util.*;

public class Main {
    public static InputReader in = new InputReader(new BufferedInputStream(System.in));
    public static PrintWriter out = new PrintWriter(System.out);
    public static int t, n, m, id, area;
    public static int[][] Map;
    public static String s;
    public static int[] pre;
    public static HashSet<Integer> num;
    public static HashSet<Integer> f;
    public static Kuai[] k;

    public static void main(String[] args) {
        t = in.nextInt();
        while (t-- > 0) {
            Map = new int[15][15];
            pre = new int[200];
            k = new Kuai[200];
            num = new HashSet<>();
            f = new HashSet<>();
            area = 0;
            n = in.nextInt();
            m = in.nextInt();
            for (int i = 0; i < n; i++) {
                s = in.nextLine();
                for (int j = 0; j < m; j++) {
                    Map[i][j] = s.charAt(j) - '0';
                    num.add(Map[i][j]);
                    id = i * m + j;
                    k[id] = new Kuai();
                    k[id].id = id;
                    k[id].minx = i;
                    k[id].miny = j;
                    k[id].maxx = i;
                    k[id].maxy = j;
                    pre[id] = id;
                }
            }
            for (int i = 0; i < n; i++) {
                for (int j = 0; j < m; j++) {
                    if (i - 1 >= 0 && Map[i][j] == Map[i-1][j]) join(i*m+j, (i-1)*m+j);
                    else if (j - 1 >= 0 && Map[i][j] == Map[i][j-1]) join(i*m+j, i*m+j-1);
                }
            }
            for (int i = 0; i < n; i++) {
                for (int j = 0; j < m; j++) {
                    int p = find(i*m+j);
                    f.add(p);
                    if (i*m+j == p) area += (k[p].maxx-k[p].minx+1) * (k[p].maxy-k[p].miny+1);
                }
            }
            if (f.size() == num.size() && area == n*m) {
                out.println("YES");
                out.flush();
            } else {
                out.println("NO");
                out.flush();
            }
        }
        out.close();
    }

    static class Kuai {
        int id, minx, miny, maxx, maxy;
    }

    static int find(int x) {
        if (x == pre[x]) return pre[x];
        else
            return pre[x] = find(pre[x]);
    }

    static void join(int x, int y) {
        int fx = find(x), fy = find(y);
        if (fx != fy) {
            pre[fx] = fy;
            k[fy].minx = Math.min(k[fy].minx, k[fx].minx);
            k[fy].maxx = Math.max(k[fy].maxx, k[fx].maxx);
            k[fy].miny = Math.min(k[fy].miny, k[fx].miny);
            k[fy].maxy = Math.max(k[fy].maxy, k[fx].maxy);
        }
    }

    static class InputReader {
        public BufferedReader reader;
        public StringTokenizer tokenizer;

        public InputReader(InputStream stream) {
            reader = new BufferedReader(new InputStreamReader(stream), 32768);
            tokenizer = null;
        }

        public String next() {
            while (tokenizer == null || !tokenizer.hasMoreTokens()) {
                try {
                    tokenizer = new StringTokenizer(reader.readLine());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return tokenizer.nextToken();
        }

        public String nextLine() {
            String str = null;
            try {
                str = reader.readLine();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return str;
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }

        public long nextLong() {
            return Long.parseLong(next());
        }

        public Double nextDouble() {
            return Double.parseDouble(next());
        }

        public BigInteger nextBigInteger() {
            return new BigInteger(next());
        }

    }
}

There is also a simpler solution: traverse the entire matrix and encounter a number that has not been traversed, use this point as the upper left corner of the rectangle, and find the maximum column subscript maxy of the same column as the upper left corner point and the maximum row subscript of the same column maxx, then the number can only meet the requirements if it is all within this rectangle, and the matrix must be all the number, you can traverse this small rectangle to see if there are other numbers, if there is, mark the answer as NO directly, In the process of judging the rectangle, the visited position can be marked to reduce the complexity. If there is the same number that is not in the rectangle, the answer is also directly NO. This rectangle that can be used to store a certain number has appeared.

Code:

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.math.BigInteger;
import java.util.*;

public class Main {
    public static InputReader in = new InputReader(new BufferedInputStream(System.in));
    public static PrintWriter out = new PrintWriter(System.out);
    public static int t, n, m, flag;
    public static char[][] Map;
    public static String s;
    public static int[][] vis;
    public static HashSet<Character> num;

    public static void main(String[] args) {
        t = in.nextInt();
        while (t-- > 0) {
            Map = new char[15][15];
            vis = new int[15][15];
            num = new HashSet<>();
            flag = 0;
            n = in.nextInt();
            m = in.nextInt();
            for (int i = 0; i < n; i++) {
                s = in.nextLine();
                for (int j = 0; j < m; j++) {
                    Map[i][j] = s.charAt(j);
                }
            }
            for (int i = 0; i < n; i++) {
                for (int j = 0; j < m; j++) {
                    if (vis[i][j] == 0) {
                        if (num.contains(Map[i][j]) == true) {
                            flag = 1;
                            break;
                        } else {
                            num.add(Map[i][j]);
                            int maxx = i + 1, maxy = j + 1;
                            for (; maxx < n; maxx++)
                                if (Map[maxx][j] != Map[i][j]) break;
                            for (; maxy < m; maxy++)
                                if (Map[i][maxy] != Map[i][j]) break;
                            if (check(i, j, maxx-1, maxy-1) == 1) {
                                flag = 1;
                                break;
                            }
                        }
                    }
                }
                if (flag == 1) break;
            }
            if (flag == 0) {
                out.println("YES");
                out.flush();
            } else {
                out.println("NO");
                out.flush();
            }
        }
        out.close();
    }

    static int check(int x, int y, int maxx, int maxy) {
        for (int i = x; i <= maxx; i++) {
            for (int j = y; j <= maxy; j++) {
                if (Map[i][j] != Map[x][y]) return 1;
                vis[i][j] = 1;
            }
        }
        return 0;
    }

    static class InputReader {
        public BufferedReader reader;
        public StringTokenizer tokenizer;

        public InputReader(InputStream stream) {
            reader = new BufferedReader(new InputStreamReader(stream), 32768);
            tokenizer = null;
        }

        public String next() {
            while (tokenizer == null || !tokenizer.hasMoreTokens()) {
                try {
                    tokenizer = new StringTokenizer(reader.readLine());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return tokenizer.nextToken();
        }

        public String nextLine() {
            String str = null;
            try {
                str = reader.readLine();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return str;
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }

        public long nextLong() {
            return Long.parseLong(next());
        }

        public Double nextDouble() {
            return Double.parseDouble(next());
        }

        public BigInteger nextBigInteger() {
            return new BigInteger(next());
        }

    }
}

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326526839&siteId=291194637