2023-11-15:用go语言,如果一个正方形矩阵上下对称并且左右对称,对称的意思是互为镜像, 那么称这个正方形矩阵叫做神奇矩阵, 比如 : 1 5 5 1 6 3 3 6 6 3 3 6 1 5
2023-11-15:用go语言,如果一个正方形矩阵上下对称并且左右对称,对称的意思是互为镜像,
那么称这个正方形矩阵叫做神奇矩阵,
比如 :
1 5 5 1
6 3 3 6
6 3 3 6
1 5 5 1
这个正方形矩阵就是神奇矩阵。
给定一个大矩阵n*m,返回其中神奇矩阵的数目。
1 <= n,m <= 1000。
来自左程云。
答案2023-11-15:
go代码用灵捷3.5编写。
大体过程如下:
1.定义常量MAXN为1001,定义常量baser为491,定义常量basec为499。
2.定义数组powr和powc,分别计算baser和basec的幂次,用于后续计算哈希值。
3.定义数组arr1、arr2、arr3,分别存储原数组、上下对称数组、左右对称数组。
4.定义数组sum1、sum2、sum3,分别存储三个数组的前缀哈希和。
5.通过循环读取输入的n、m和矩阵元素,并顺便把元素存入arr1、arr2、arr3对应位置。
6.构建arr1、arr2、arr3的前缀哈希和,存入sum1、sum2、sum3中。
7.定义函数hash,用于计算矩阵中(a,b)到(c,d)范围内的哈希值。
8.定义函数ok,用于判断以(a,b)到(c,d)范围内的正方形是否为神奇矩阵。
9.定义函数number,用于统计大矩阵中神奇矩阵的数量。分别计算奇数长度和偶数长度的正方形数量,返回总数量。
10.在主函数中调用上述各个函数,输出最终结果。
11.总时间复杂度为$O(n^2 * logn)$,总额外空间复杂度为$O(n^2)$。
go完整代码如下:
package main
import (
"fmt"
)
const MAXN int = 1001
const baser int = 491
const basec int = 499
var powr [MAXN]int64
var powc [MAXN]int64
var arr1 [MAXN][MAXN]int
var arr2 [MAXN][MAXN]int
var arr3 [MAXN][MAXN]int
var sum1 [MAXN][MAXN]int64
var sum2 [MAXN][MAXN]int64
var sum3 [MAXN][MAXN]int64
var n int
var m int
func init() {
powr[0] = 1
powc[0] = 1
for i := 1; i < MAXN; i++ {
powr[i] = powr[i-1] * int64(baser)
}
for i := 1; i < MAXN; i++ {
powc[i] = powc[i-1] * int64(basec)
}
}
func buildHash(arr *[MAXN][MAXN]int, sum *[MAXN][MAXN]int64) {
for i := 1; i <= n; i++ {
for j := 1; j <= m; j++ {
sum[i][j] = sum[i][j-1]*int64(basec) + int64(arr[i][j])
}
}
for i := 1; i <= n; i++ {
for j := 1; j <= m; j++ {
sum[i][j] += sum[i-1][j] * int64(baser)
}
}
}
func hash(sum *[MAXN][MAXN]int64, a int, b int, c int, d int) int64 {
ans := sum[c][d] - sum[a-1][d]*powr[c-a+1] - sum[c][b-1]*powc[d-b+1] + sum[a-1][b-1]*powr[d-b+1]*powc[c-a+1]
return ans
}
func number() int {
ans := 0
// 奇数长度,实点做中心
for i := 1; i <= n; i++ {
for j := 1; j <= m; j++ {
l := 1
r := min(min(i, n-i+1), min(j, m-j+1))
find := 1
var m int
for l <= r {
m = (l + r) / 2
if ok(i-m+1, j-m+1, i+m-1, j+m-1) {
find = m
l = m + 1
} else {
r = m - 1
}
}
ans += find
}
}
// 偶数长度
// 虚点做中心
for i := 1; i < n; i++ {
for j := 1; j < m; j++ {
// 左上角点为代表
l := 1
r := min(min(i, j), min(n-i, m-j))
find := 0
var m int
for l <= r {
m = (l + r) / 2
if ok(i-m+1, j-m+1, i+m, j+m) {
find = m
l = m + 1
} else {
r = m - 1
}
}
ans += find
}
}
return ans
}
func ok(a int, b int, c int, d int) bool {
if a == c {
return true
}
h1 := hash(&sum1, a, b, c, d)
h2 := hash(&sum2, n-c+1, b, n-a+1, d)
h3 := hash(&sum3, a, m-d+1, c, m-b+1)
return h1 == h2 && h1 == h3
}
func min(x int, y int) int {
if x < y {
return x
}
return y
}
func main() {
inputs := []int{5, 5,
4, 2, 4, 4, 4,
3, 1, 4, 4, 3,
3, 5, 3, 3, 3,
3, 1, 5, 3, 3,
4, 2, 1, 2, 4}
ii := 0
n = inputs[ii]
ii++
m = inputs[ii]
ii++
for i := 1; i <= n; i++ {
for j := 1; j <= m; j++ {
arr1[i][j] = inputs[ii]
ii++
arr2[n-i+1][j] = arr1[i][j]
arr3[i][m-j+1] = arr1[i][j]
}
}
buildHash(&arr1, &sum1)
buildHash(&arr2, &sum2)
buildHash(&arr3, &sum3)
fmt.Println(number())
}

2023-11-15:用go语言,如果一个正方形矩阵上下对称并且左右对称,对称的意思是互为镜像, 那么称这个正方形矩阵叫做神奇矩阵, 比如 : 1 5 5 1 6 3 3 6 6 3 3 6 1 5的更多相关文章
- 使用C语言实现一个虚拟机
使用C语言实现一个虚拟机 2015-6-22 21:32| 发布者: joejoe0332| 查看: 2891| 评论: 0|原作者: leoxu, Serval, 社会主义好, lostTemple ...
- linux c语言编写一个shell壳
目的:我们要用c语言编写一个shell可以运行在linux机器上的. 介绍:shell所在的层次 我们要做的是操作系统,用于用户与操作系统进行交互的myhsell 思路:用户输入 一行字符串,我们先 ...
- C语言的本质(15)——C语言的函数接口入门
C语言的本质(15)--C语言的函数接口 函数的调用者和其实现者之间存在一个协议,在调用函数之前,调用者要为实现者提供某些条件,在函数返回时,实现者完成调用者需要的功能. 函数接口通过函数名,参数和返 ...
- 11.15 Daily Scrum
今天是假期回来的第一个周末,也是我们团队的又一次进度汇总总结和调试工作开展,鉴于一周以来大家的工作有了很大的成果,所以,本次召开的会议主旨在于解决一些开发方面的细节问题,达成共识,为日后进一步的功能方 ...
- 2017.11.13 在C语言中是否能用函数实现模块化程序设计
第七章 用函数实现模块化程序设计 (1)为什么要用函数? @function既是函数也是功能.函数就是用来完成一定功能的的(函数就是功能),函数名就是给这个功能起一个名字,一个C程序可由一个主函数和若 ...
- 2017-3-13 leetcode 4 11 15
ji那天居然早起了,惊呆我了,眼睛有点儿疼,一直流泪....继续保持 ========================================================== leetco ...
- Python3.7&Django1.11.15 兼容性问题
环境: 1. Windows10 2. python3.7 3. Django1.11.15 启动Django时抛出以下异常: Unhandled exception in thread starte ...
- JZOJ 【NOIP2016提高A组集训第16场11.15】兔子
JZOJ [NOIP2016提高A组集训第16场11.15]兔子 题目 Description 在一片草原上有N个兔子窝,每个窝里住着一只兔子,有M条路径连接这些窝.更特殊地是,至多只有一个兔子窝有3 ...
- 使用Java语言编写一个五子棋UI界面并实现网络对战功能(非局域网)
使用Java语言编写一个五子棋UI界面并实现网络对战功能(非局域网) 一,前期准备 1,Java IDE(Eclipse)与JDK的安装与配置jdk-15.0.1-免配置路径版提取码:earu免安装版 ...
- Sprint1(第二天11.15)
Sprint1(第二天11.15) Sprint1第一阶段 1.类名:软件工程-第一阶段 2.时间:11.14-11.23 3.选题内容:web版-餐厅到店点餐系统 4.团队博客地址: http:// ...
随机推荐
- c语言代码练习15
//使用togo跳转代码,阻止关机#define _CRT_SECURE_NO_WARNINGS 1 #include <stdio.h> #include <string.h> ...
- Docker 安装 Redis 单机&集群总结
前言 Redis 是一个开源的使用 ANSI C 语言编写.遵守 BSD 协议.支持网络.可基于 内存 . 分布式 .可选持久性的键值对( Key-Value )存储数据库 redis版本:redis ...
- 如何通过代码混淆绕过苹果机审,解决APP被拒问题
目录 iOS代码混淆 功能分析 实现流程 类名修改 方法名修改 生成垃圾代码 替换png等静态资源MD5 info.plist文件添加垃圾字段 功能分析 实现流程 类名修改 方法名修改 生成垃圾代码 ...
- 手写商用Java虚拟机HotSpot,疯狂磨砺技术中
在当前Java行业激烈竞争的形式下,唯有掌握技术,心中才不能慌.在多年前,我就开始苦练底层技术,但是眼看百遍也不如手过一遍,所以我打算把虚拟机的精华实现部分用手敲出来,这个过程注定不会轻松,但是心态不 ...
- kubernetes发布周期
前言 页面介绍了版本发布的一些时间点和PR的要求,通过了解k8s的发布周期来规划自己的版本选择. 合并PR的要求 如果你希望将你的代码合并到官方代码仓库中,不同的开发阶段需要有不同的标签和里程碑.也是 ...
- Facade 外观模式简介与 C# 示例【结构型5】【设计模式来了_10】
〇.简介 1.什么是外观模式? 一句话解释: 将一系列需要一起进行的操作,封装到一个类中,通过对某一个方法的调用,自动完成一系列操作. 外观模式是一种简单而又实用的设计模式,它的目的是提供一个统一 ...
- 【2023年更新】git 常用口令
1.已关联远程 fatal: remote origin already exists. 先输入$ git remote rm origin(删除关联的origin的远程库) 2.关联新远程 ...
- Keil MDK忽略警告, 包括文件末尾空白行, 未使用等警告
首先应该了解为什么Keil MDK 会有这样的警告, 原因简单说就是C99规定了要在末尾行加回车 一. 你可以使用格式化工具对所有源文件进行一次格式化处理. 二. 在Keil MDK中查看 Build ...
- STL unordered类容器浅谈
一个代码: #include<cstdio> #include<vector> #include<functional> #include<algorithm ...
- 代替gets()的新操作
1 scanf("%[^\n]", s); ^是"非" \n是换行 所以这就是一直读到\n才结束