首页 > 其他分享 >CSC1003 A2 T3 Ascii Art

CSC1003 A2 T3 Ascii Art

时间:2024-10-30 15:31:26浏览次数:7  
标签:Art int sum len ++ A2 哈希 Ascii 字母

A2 T3 Ascii Art

Tutorial by George (Wechat ID: Geo1123rge).

Keep it private before the assignment ends.

这里用哈希做法。

读入字符模板

import java.util.*;

public class Main {

    public static void main(String[] args) {
        Scanner S = new Scanner(System.in);
        int[] record = new int[26]; // 每个大字母的哈希值
        for (int i = 0; i < 26; ++i) {
            String[] s = new String[7]; // 所有大字母高度都是 7
            int[] len = new int[7]; // 这里不必要,但是因为 String 类的 .length() 复杂度是 O(length) 的,所以存一下快一点。还有另外一个作用就是辅助后面删除字符串尾空格
            int mx = 0; // 一定要求出字母每行的最大宽度,因为单个字母的最大宽度就是它在单词里的宽度
            for (int j = 0; j < 7; ++j) {
                s[j] = S.nextLine();
                while (s[j].length() < 2) s[j] = S.nextLine(); // 丢弃空行
                len[j] = s[j].length();
                while (len[j] > 0 && s[j].charAt(len[j] - 1) != '#') --len[j]; // 注意这很重要,字符串尾可能会有空格
                if (len[j] > mx) mx = len[j];
            }
            int mod = 998244353; // 哈希模数,具体作用看后面
            int sum = 0;
            for (int j = 0; j < 7; ++j) for (int k = 0; k < mx; ++k) { // 对整个 7 * mx 的方阵哈希
                sum = sum * 2 % mod;
                if (k < len[j] && s[j].charAt(k) == '#') sum = (sum + 1) % mod;
            }
            // 仔细观察上面两行,如果不看 % mod 且 sum 不会爆 int,那么求出来的 sum 就是把大字母矩阵 7 行接在一起后的二进制数。但是这个数太大,所以对 998244353 取模——我们发现所有相同字母这样计算后的值(可称为哈希值)都是一样的,而不同字母都是不一样的(这是个巧合,但是每个字母有 998244353 种哈希值的可能取值,所以出现相同的概率真的很小,而这里的概率就是 0,对比输出的 record[i] 即可知)
            // System.out.println((char)(i + 'A') + ": " + sum);
            // for (int j = 0; j < 7; ++j) System.out.print(len[j] + " ");
            // System.out.println();
            record[i] = sum;
        }
        for (int i = 0; i < 26; ++i) System.out.print(record[i] + ", ");
        System.out.println();
    }
}

输出结果:

557138, 783037474, 253713189, 246166578, 57958169, 57958106, 247060227, 838444457, 258369135, 355913267, 302150034, 8613417, 592770654, 528807205, 512275521, 782249380, 518568510, 785398183, 132274982, 567184348, 167355700, 117667438, 565824435, 495066258, 206529121, 921117289, 

解题代码

import java.util.*;

public class Main {

    public static void main(String[] args) {
        Scanner S = new Scanner(System.in);
        int[] h = {557138, 783037474, 253713189, 246166578, 57958169, 57958106, 247060227, 838444457, 258369135, 355913267, 302150034, 8613417, 592770654, 528807205, 512275521, 782249380, 518568510, 785398183, 132274982, 567184348, 167355700, 117667438, 565824435, 495066258, 206529121, 921117289}; // 把上题的输出存成数组,h[i] 是第 i 个大字母的哈希值(A - h[0], B - h[1], etc.)
        // about how h[] is created, look at H
        int n = S.nextInt();
        while (n-- > 0) {
            String[] s = new String[7];
            int[] len = new int[7];
            int mx = 0;
            for (int j = 0; j < 7; ++j) {
                s[j] = S.nextLine();
                while (s[j].length() < 2) s[j] = S.nextLine();
                len[j] = s[j].length();
                while (len[j] > 0 && s[j].charAt(len[j] - 1) != '#') --len[j];
                if (len[j] > mx) mx = len[j];
            } // 读入一个单词的字符串数组同前一份代码
            int mod = 998244353;
            int last = 0; // 见下,记录上一个字母分隔后的下一列
            String res = "";
            for (int k = 0; k < mx; ++k) {
                boolean empty = true;
                for (int j = 0; j < 7; ++j) if (k < len[j] && s[j].charAt(k) == '#') {
                    empty = false;
                    break;
                } 
                // empty 表示列 k 是否为空,如果是空的,表示这里有一个字母分隔
                if (empty) {
                    int sum = 0;
                    for (int j = 0; j < 7; ++j) for (int p = last; p < k; ++p) {
                        sum = sum * 2 % mod;
                        if (p < len[j] && s[j].charAt(p) == '#') sum = (sum + 1) % mod;
                    } // 同前一份代码,把两个空列间的大字母矩阵展开哈希
                    for (int x = 0; x < 26; ++x) if (h[x] == sum) { // 判断是不是字母 (char)(x + 'A')
                        res += (char)(x + 'A');
                        break;
                    }
                    last = k + 1; // 记录上一个字母分隔后的下一列
                }
            }
			// 下面:别忘了最后一个空列之后虽然已没有空列,但是还有一个大字母矩阵,所以还要展开哈希
            int sum = 0;
            for (int j = 0; j < 7; ++j) for (int p = last; p < mx; ++p) {
                sum = sum * 2 % mod;
                if (p < len[j] && s[j].charAt(p) == '#') sum = (sum + 1) % mod;
            }
            for (int x = 0; x < 26; ++x) if (h[x] == sum) {
                res += (char)(x + 'A');
                break;
            } // 同上
            System.out.println(res);
        }
    }
}

题目至此解决。哈希的好处不关是可以减少代码长度,也可以让我们对复杂的字母矩阵获得更直观的把握。在复杂的代码中一份代码读入简单的东西然后代码进行几番复杂的计算之后可能又得到一个简单的值,这个时候假如能在某个地方将代码打断,将前半部分的成果总结为几个简单,甚至固定的数据,就再好不过了,能大大减少代码的复杂度,增加代码的正确性。

标签:Art,int,sum,len,++,A2,哈希,Ascii,字母
From: https://www.cnblogs.com/Pizza1123/p/18515941

相关文章

  • quartus ii或prime仿真及常见问题
    前言长时间不用会忘所以记录一下几个注意事项提示:以下是本篇文章正文内容,下面案例可供参考一、将要仿真的工程文件设为top如果有多个工程文件一定需要将你要仿真的工程文件设为top,不然你的modelsim打开为空白并报错。二、modelsim的路径设置正确在tools的options设......
  • ECharts饼图-日历饼图,附视频讲解与代码下载
    引言: 在数据可视化的世界里,ECharts凭借其丰富的图表类型和强大的配置能力,成为了众多开发者的首选。今天,我将带大家一起实现一个饼图图表,通过该图表我们可以直观地展示和分析数据。此外,我还将提供详细的视频讲解和代码下载链接,帮助大家快速上手。一、图表效果预览 二、视......
  • JS和ECharts的一些分享
    @TJS和ECharts的一些分享OC制作动态天气预测图表withEChartsandJavaScript在现代网页开发中,将复杂的数据视觉化通常能极大地增强用户体验。本文将使用ECharts,一款强大的开源可视化库,配合JavaScript来创建一个根据不同天气条件显示不同的动态液体填充图表。这种图表......
  • Shooter Game User Interface Starter
    射击游戏用户界面工具包这个工具包为射击游戏开发者提供了一套完整的UnityUI布局屏幕和预制件,旨在加速游戏界面的开发过程。以下是工具包的核心特性:屏幕布局:包含9个完整的UnityUI布局屏幕,覆盖装备、选项、游戏模式、大厅、社交、装备详情、登录、设置等多个游戏界面。......
  • FEIT Part 2 & Part 3: Software Development
    UniversityofTechnologySydney,FEIT–Assessment1Page1Assignment1–Part2&Part3:SoftwareDevelopment&ShowcaseDuedate:SundayNovember3,2024,by11:59PMWeight:55outoftotalAssessment1weight70Project:UniversityApplicati......
  • 【项目实战】分布式日志搜索系统之Elastic Stack日志抽取(filebeat、heartbeat、packet
    一、ElasticStack是什么?ElasticStack,以前称为ELKStack,是一套开源的日志分析解决方案。ElasticStack,由Elastic公司开发和维护。ElasticStack,包括了几个核心组件,这些组件协同工作以帮助用户收集、处理、存储、搜索和可视化数据。ElasticStack,因其灵活性和强大的功能......
  • LightningChart部署到Windows11某些电脑,无法启动问题
       问题经过注册表排查、SDK排查,均没有解决问题。   在可以运行的电脑上,全盘搜索LightningChat、Arction(厂家名称)比对,终于发现一个temp目录下的Arction.DirectX_32目录以及下边俩个dll:D3DCompiler_43.dll、d3dx11_43.dll,删除了就启动不了。   解决方案就是增......
  • 第四届智慧交通与城市工程国际学术会议 (STCE 2024) 2024 4th International Conferenc
    文章目录一、会议详情二、重要信息三、大会介绍四、出席嘉宾五、征稿主题六、咨询一、会议详情二、重要信息大会官网:https://ais.cn/u/vEbMBz提交检索:EICompendex、IEEEXplore、Scopus三、大会介绍第四届智慧交通与城市工程国际学术会议(STCE2024)将于2024年12......
  • 第四届智慧交通与城市工程国际学术会议 (STCE 2024) 2024 4th International Conferen
    @目录一、会议详情二、重要信息三、大会介绍四、出席嘉宾五、征稿主题一、会议详情二、重要信息大会官网:https://ais.cn/u/vEbMBz提交检索:EICompendex、IEEEXplore、Scopus三、大会介绍第四届智慧交通与城市工程国际学术会议(STCE2024)将于2024年12月6-8日在重庆隆重举......
  • 毕业设计:python哔哩哔哩数据可视化分析系统 B站 bilibili数据 Flask框架 Echarts可视
    毕业设计:python哔哩哔哩数据可视化分析系统B站bilibili数据Flask框架Echarts可视化(源码)✅1、项目介绍技术栈:python语言、Flask框架、Echarts可视化、MySQL数据库、词云图、HTML2、项目界面(1)系统首页—数据概况(2)B站评论弹幕分析(3)B站作者分析(4)B站视频可视化分......