首页 > 其他分享 >abc336F 旋转矩阵谜题

abc336F 旋转矩阵谜题

时间:2024-03-12 15:38:07浏览次数:13  
标签:node const int rep h1 矩阵 谜题 abc336F

有一个大小为W*H的矩阵,每个格子里分别有1 ~ W*H的某个数字,对应1 ~ W*H的一个排列。每次可以选择大小为(W-1)*(H-1)的子矩阵旋转180度。给定初始状态,问20步以内是否可以将它还原?如果可以,输出最小步数,否则输出-1。
3<=H,W<=8; 1<=a[i][j]<=H*W; a[i][j]各不相等

bfs搜索,由于每一步都有4种情况,时间复杂度为O(420),会TLE,因此改用双向bfs,时间复杂度降为O(2*410),可以通过。需要用哈希来判重。

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define rep(i,a,b) for(int i=a; i<=b; i++)
#define per(i,a,b) for(int i=b; i>=a; i--)

using node = array<array<int,9>,9>;
const int m1 = 1000000123;
const int m2 = 1000000223;
void solve() {
    int H, W;
    cin >> H >> W;
    node s{}, t{};
    map<int,int> ms, mt;
    rep(i,1,H) rep(j,1,W) cin >> s[i][j];
    rep(i,1,H) rep(j,1,W) t[i][j] = (i-1)*W+j;

    auto rotate = [&](const node &u, node &v, int x, int y) {
        v = u;
        rep(i,1,H-1) rep(j,1,W-1) {
            v[i+x][j+y] = u[H-i+x][W-j+y];
        }
    };
    auto id = [&](const node &u) -> int {
        int h1 = 0, h2 = 0;
        rep(i,1,H) rep(j,1,W) {
            h1 = (h1 * 131 + u[i][j]) % m1;
            h2 = (h2 * 131 + u[i][j]) % m2;
        }
        return (h1<<32) + h2;
    };
    auto bfs = [&](node u, map<int,int> &mp) -> void {
        int step = 0;
        queue<node> q;
        q.push(u);
        while (!q.empty() && step <= 10) {
            int cnt = q.size();
            node x{}, y{};
            rep(i,1,cnt) {
                x = q.front(); q.pop();
                mp[id(x)] = step;
                rep(i,0,1) rep(j,0,1) {
                    rotate(x, y, i, j);
                    if (mp.count(id(y)) == 0) {
                        q.push(y);
                    }
                }
            }
            step += 1;
        }
    };

    bfs(s, ms);
    bfs(t, mt);
    int ans = 100;
    for (auto &[k,v] : mt) {
        auto it = ms.find(k);
        if (it != ms.end()) {
            ans = min(ans, v + it->second);
        }
    }
    if (ans == 100) {
        ans = -1;
    }
    cout << ans;
}

signed main() {
    cin.tie(0)->sync_with_stdio(0);
    int t = 1;
    while (t--) solve();
    return 0;
}

标签:node,const,int,rep,h1,矩阵,谜题,abc336F
From: https://www.cnblogs.com/chenfy27/p/18068397

相关文章

  • [牛客]小红走矩阵
    题目思路直接套bfs模板代码#include<bits/stdc++.h>usingnamespacestd;usingll=longlong;constintN=1e3+5,INF=0x3f3f3f3f;structNode{ intx,y,s;}t,t1;chargraph[N][N];boolvis[N][N];queue<Node>q;intdx[4]={0,0,1,1};intdy[4]={-1,1,0......
  • abc332D 将矩阵A变成B的最小步数
    题面:给定两个H行W列的矩阵A和B,每次操作可以交换相邻的行或列,问是否可以将A变成B?如果可以,输出最少操作步数;如果不行,输出-1。范围:2<=H,W<=5,1<=A[i][j],B[i][j]<=1e9思路:数据规模小,直接bfs搜索,如果范围再大点可以用双向bfs优化效率。需要用到哈希来快速判重。#include<bits/std......
  • C++中OpenCV、Armadillo矩阵数据格式的转换方式
      本文介绍在C++语言中,矩阵库Armadillo的mat、vec格式数据与计算机视觉库OpenCV的Mat格式数据相互转换的方法。  在C++语言的矩阵库Armadillo与计算机视觉库OpenCV中,都有矩阵格式的数据类型;而这两个库在运行能力方面各有千秋,因此实际应用过程中,难免会遇到需要将二者的矩阵格......
  • 代码随想录算法训练营第二天| 977.有序数组的平方、 209.长度最小的子数组、 59.螺旋
    977.有序数组的平方https://leetcode.cn/problems/squares-of-a-sorted-array/description/publicstaticint[]sortedSquares(int[]nums){intleft=0;intright=nums.length-1;int[]result=newint[nums.length];intwrite=......
  • 矩阵乘法
    GEMM(GeneralMatrixMultiplication)-通用矩阵乘BLAS(BasicLinearAlgebraSubprograms)-基本线性代数子程序SGEMM(SingleprecisionGeneralMatrixMultiply)-单精度矩阵乘法DGEMM(DoubleprecisionGeneralMatrixMultiply)-双精度矩阵乘法CGEMM(Complexsingl......
  • matlab教程_台大lecture1基本操作和矩阵输入
    matlab教程视频matlabascalculatorcommendline直接用命令行计算部分ans是结果运算法则和平时一样((),^乘除加减)onlinehelpeg:helpsin&直接搜索嵌套式公式sin(cos(pi))==cos(pi)sin(ans)其中,ans是第一个的结果变量可以用who查看变量,whos详细信息一些保留......
  • 矩阵快速幂
    对于矩阵快速幂,其作用能够达到快速递推公式的作用这里先定义一个矩阵structmartix{intx[105][105];martix(){memset(x,0,sizeofx);}};首先看如何进行矩阵计算,由线性代数知:martixcacl(martixa,martixb){martixc;for(inti=1;i<=n;i++)......
  • 最大字段和,区间矩阵
    最大字段和原题链接:P1115最大子段和-洛谷|计算机科学教育新生态(luogu.com.cn)解析:经典动态规划:最大子数组问题-知乎(zhihu.com)我写的代码:#include<iostream>#include<algorithm>#include<cstring>usingnamespacestd;constintN=2e5+10;inta[N],dp[N]......
  • 邻接矩阵 存储图
    存储图可以用邻接表和邻接矩阵以下代码来自https://www.acwing.com/blog/content/405///对于每个点k,开一个单链表,存储k所有可以走到的点。h[k]存储这个单链表的头结点inth[N],e[N],ne[N],idx,w[N];//添加一条边a->b,权重是wvoidadd(inta,intb,intw){e[id......
  • 矩阵爆破逆向之条件断点的妙用
    不知道你是否使用过IDA的条件断点呢?在IDA进阶使用中,它的很多功能都有大作用,比如:ida-trace来跟踪调用流程。同时IDA的断点功能也十分强大,配合IDA-python的输出语句能够大杀特杀!那么本文就介绍一下这个功能点,使用z3来秒解题目。条件断点什么是条件断点呢?条件断点(ConditionalBrea......