枚举求解"单词方阵"(洛谷P1101题题解,Java语言描述)

题目要求

P1101题目链接

在这里插入图片描述在这里插入图片描述

分析

可以用DFS做,但我立下了个Flag,所以就用了朴素的枚举来做。。。。

结果,我的天哪,做了好几个小时……

其实这种地图题,真的适合 DFS or BFS or DP 这种,这种八向枚举,太难受了。
好处是可以不去分析递归问题或者动态转移方程。

我开两个数组,一个是char类型,一个是byte类型(其实是相当于boolean类型)。
题好像没给数值边界,所以我怕爆炸,使用BufferedReader而不是Scanner(其实这种也不是读数值,可能差不到太多)。

DFS等搜索算法写法的思路是从一个点开始逐步递归到边界,每次八向尝试。但朴素暴力算法则不同。

我们把问题全局看,不着眼于某个点及其下一步的分散走向,有四大类:

  1. 每一行
  2. 每一列
  3. 每一个长度大于7的“主对角线”
  4. 每一个长度大于7的“次对角线”

想要反向,其实可以换个思路,就是改为判断"yizhong"反过来的"gnohziy",这样就简化了问题,把把八种情况化作四种情况。

再就是,对角线要在两侧开,所以要细分情况。

这题其实我这么写很难写,需要考虑整个的边界值,自闭……

再就是一个核心算法了:数组中串的模式匹配。
先使用StringBuilder把数组元素遍历从而凑成串,然后使用indexOf()和replace(),在循环中进行多次匹配,因为可能有多次出现。(这种用法我在其他洛谷题题解博客中写到过,挺实用)

避坑指南

错了三次。

第一次是repeat()的问题,这个其实在代码注释中也说了,洛谷的Java8不支持repeat()但Idea疯狂暗示使用这个,没办法你只能改。

第二次是空格问题,我习惯性打印了空格,把每个元素分开,但这题没分隔符。

第三次就是发现了可能在一行、一列、一对角线中有多次重复串,需要多次匹配,就把代码几乎翻了一遍。
测试数据点3:
in

16
qyizhongqyizhong
gydthkjygydthkjy
nwidghjinwidghji
orbzsfgzorbzsfgz
hhgrhwthhhgrhwth
zzzzzozozzzzzozo
iwdfrgngiwdfrgng
yyyyggggyyyygggg
qyizhongqyizhong
gydthkjygydthkjy
nwidghjinwidghji
orbzsfgzorbzsfgz
hhgrhwthhhgrhwth
zzzzzozozzzzzozo
iwdfrgngiwdfrgng
yyyyggggyyyygggg

out

*yizhong*yizhong
gy******gy******
n*i*****n*i*****
o**z****o**z****
h***h***h***h***
z****o**z****o**
i*****n*i*****n*
y******gy******g
*yizhong*yizhong
gy******gy******
n*i*****n*i*****
o**z****o**z****
h***h***h***h***
z****o**z****o**
i*****n*i*****n*
y******gy******g

AC代码(Java语言描述)

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        int num = Integer.parseInt(reader.readLine());
        char[][] chars = new char[num][num];
        byte[][] flags = new byte[num][num];
        //初始化
        for (int i = 0; i < num; i++) {
            char[] temp = reader.readLine().toCharArray();
            for (int j = 0; j < num; j++) {
                chars[i][j] = temp[j];
            }
        }
        reader.close();
        if (num < 7) {
            StringBuilder result = new StringBuilder();
            for (int i = 0; i < num; i++) {
                result.append('*');
            }
            //洛谷不识别下面的代码
            //String result = "*";
            //result = result.repeat(num);
            for (int i = 0; i < num; i++) {
                System.out.println(result);
            }
            return;
        }
        //水平方向
        for (int i = 0; i < num; i++) {
            StringBuilder temp = new StringBuilder(), temp2;
            for (int j = 0; j < num; j++) {
                temp.append(chars[i][j]);
            }
            temp2 = temp;
            int index = temp.indexOf("yizhong");
            while (index >= 0) {
                for (int j = index; j < index+7; j++) {
                    if (flags[i][j] == 0) {
                        flags[i][j] = 1;
                    }
                }
                temp.replace(index, index+7, "zzzzzzz");
                index = temp.indexOf("yizhong");
            }
            index = temp2.indexOf("gnohziy");
            while (index >= 0) {
                for (int j = index; j < index+7; j++) {
                    if (flags[i][j] == 0) {
                        flags[i][j] = 1;
                    }
                }
                temp.replace(index, index+7, "zzzzzzz");
                index = temp2.indexOf("gnohziy");
            }
        }
        //竖直方向
        for (int j = 0; j < num; j++) {
            StringBuilder temp = new StringBuilder(), temp2;
            for (int i = 0; i < num; i++) {
                temp.append(chars[i][j]);
            }
            temp2 = temp;
            int index = temp.indexOf("yizhong");
            while (index >= 0) {
                for (int i = index; i < index+7; i++) {
                    if (flags[i][j] == 0) {
                        flags[i][j] = 1;
                    }
                }
                temp.replace(index, index+7, "zzzzzzz");
                index = temp.indexOf("yizhong");
            }
            index = temp2.indexOf("gnohziy");
            while (index >= 0) {
                for (int i = index; i < index+7; i++) {
                    if (flags[i][j] == 0) {
                        flags[i][j] = 1;
                    }
                }
                temp.replace(index, index+7, "zzzzzzz");
                index = temp2.indexOf("gnohziy");
            }
        }
        //主对角线方向
        //下方扫描
        for (int i = 0; i < num-7; i++) {
            StringBuilder temp = new StringBuilder(), temp2;
            int x = i, y = 0;
            while (x < num) {
                temp.append(chars[x++][y++]);
            }
            temp2 = temp;
            int index = temp.indexOf("yizhong");
            while (index >= 0) {
                for (int j = i+index, k = index; k < index+7; j++, k++) {
                    if (flags[j][k] == 0) {
                        flags[j][k] = 1;
                    }
                }
                temp.replace(index, index+7, "zzzzzzz");
                index = temp.indexOf("yizhong");
            }
            index = temp2.indexOf("gnohziy");
            while (index >= 0) {
                for (int j = i+index, k = index; k < index+7; j++, k++) {
                    if (flags[j][k] == 0) {
                        flags[j][k] = 1;
                    }
                }
                temp.replace(index, index+7, "zzzzzzz");
                index = temp2.indexOf("gnohziy");
            }
        }
        //主对角线方向
        //右侧扫描
        for (int i = 0; i < num-7; i++) {
            StringBuilder temp = new StringBuilder(), temp2;
            int x = 0, y = i;
            while (y < num) {
                temp.append(chars[x++][y++]);
            }
            temp2 = temp;
            int index = temp.indexOf("yizhong");
            while (index >= 0) {
                for (int j = i+index, k = index; k < index+7; j++, k++) {
                    if (flags[k][j] == 0) {
                        flags[k][j] = 1;
                    }
                }
                temp.replace(index, index+7, "zzzzzzz");
                index = temp.indexOf("yizhong");
            }
            index = temp2.indexOf("gnohziy");
            while (index >= 0) {
                for (int j = i+index, k = index; k < index+7; j++, k++) {
                    if (flags[k][j] == 0) {
                        flags[k][j] = 1;
                    }
                }
                temp.replace(index, index+7, "zzzzzzz");
                index = temp2.indexOf("gnohziy");
            }
        }
        //次对角线方向
        //下方扫描
        for (int i = 0; i < num-6; i++) {
            StringBuilder temp = new StringBuilder(), temp2;
            int x = i, y = num-1;
            while (x < num) {
                temp.append(chars[x++][y--]);
            }
            temp2 = temp;
            int index = temp.indexOf("yizhong");
            while (index >= 0) {
                for (int j = i+index, k = num-index-1; j < i+index+7; j++, k--) {
                    if (flags[j][k] == 0) {
                        flags[j][k] = 1;
                    }
                }
                temp.replace(index, index+7, "zzzzzzz");
                index = temp.indexOf("yizhong");
            }
            index = temp2.indexOf("gnohziy");
            while (index >= 0) {
                for (int j = i+index, k = num-index-1; j < i+index+7; j++, k--) {
                    if (flags[j][k] == 0) {
                        flags[j][k] = 1;
                    }
                }
                temp.replace(index, index+7, "zzzzzzz");
                index = temp2.indexOf("gnohziy");
            }
        }
        //次对角线方向
        //左侧扫描
        for (int i = num-1; i > 5; i--) {
            StringBuilder temp = new StringBuilder(), temp2;
            int x = 0, y = i;
            while (y > 0) {
                temp.append(chars[x++][y--]);
            }
            temp2 = temp;
            int index = temp.indexOf("yizhong");
            while (index >= 0) {
                for (int j = index, k = i-index; j < index+7; j++, k--) {
                    if (flags[j][k] == 0) {
                        flags[j][k] = 1;
                    }
                }
                temp.replace(index, index+7, "zzzzzzz");
                index = temp.indexOf("yizhong");
            }
            index = temp2.indexOf("gnohziy");
            while (index >= 0) {
                for (int j = index, k = i-index; j < index+7; j++, k--) {
                    if (flags[j][k] == 0) {
                        flags[j][k] = 1;
                    }
                }
                temp.replace(index, index+7, "zzzzzzz");
                index = temp2.indexOf("gnohziy");
            }
        }
        //打印结果
        for (int i = 0; i < num; i++) {
            StringBuilder result = new StringBuilder();
            int j;
            for (j = 0; j < num; j++) {
                if (flags[i][j] == 0) {
                    result.append('*');
                } else {
                    result.append(chars[i][j]);
                }
            }
            System.out.println(result);
        }
    }
}
发布了717 篇原创文章 · 获赞 1513 · 访问量 69万+

猜你喜欢

转载自blog.csdn.net/weixin_43896318/article/details/104865530