当前位置: 首页 > backend >正文

P1205 [USACO1.2] 方块转换 Transformations

P1205 [USACO1.2] 方块转换 Transformations

题目描述

一块 n×nn \times nn×n 正方形的黑白瓦片的图案要被转换成新的正方形图案。写一个程序来找出将原始图案按照以下列转换方法转换成新图案的最小方式:

  • 90°90\degree90°:图案按顺时针转 90°90\degree90°

  • 180°180\degree180°:图案按顺时针转 180°180\degree180°

  • 270°270\degree270°:图案按顺时针转 270°270\degree270°

  • 反射:图案在水平方向翻转(以中央铅垂线为中心形成原图案的镜像)。

  • 组合:图案在水平方向翻转,然后再按照 1∼31 \sim 313 之间的一种再次转换。

  • 不改变:原图案不改变。

  • 无效转换:无法用以上方法得到新图案。

如果有多种可用的转换方法,请选择序号最小的那个。

只使用上述 777 个中的一个步骤来完成这次转换。

输入格式

第一行一个正整数 nnn

然后 nnn 行,每行 nnn 个字符,全部为 @-,表示初始的正方形。

接下来 nnn 行,每行 nnn 个字符,全部为 @-,表示最终的正方形。

输出格式

单独的一行包括 1∼71 \sim 717 之间的一个数字(在上文已描述)表明需要将转换前的正方形变为转换后的正方形的转换方法。

输入输出样例 #1

输入 #1

3
@-@
---
@@-
@-@
@--
--@

输出 #1

1

说明/提示

【数据范围】
对于 100%100\%100% 的数据,1≤n≤101\le n \le 101n10

USACO Training Section 1.2

提交链接

Transformations

思路分析

📦 数据结构与变量说明

变量名含义
s[19][19]原始图案
t[19][19]目标图案
temp[19][19]存储变换后的图案用于比较

🔍 函数说明与实现解析


🔹 bool check(a, b)

  • 功能: 判断两个图案是否一模一样

🔹 bool change1(s) —— 顺时针旋转 90°

  • 变换公式: temp[i][j] = s[n - 1 - j][i]

🔹 bool change2(s) —— 顺时针旋转 180°

  • 变换公式: temp[i][j] = s[n - 1 - i][n - 1 - j]

🔹 bool change3(s) —— 顺时针旋转 270°

  • 变换公式: temp[i][j] = s[j][n - 1 - i]

🔹 bool change4(s) —— 水平反射

  • 变换公式: temp[i][j] = s[i][n - 1 - j]

🔹 组合变换(反射 + 旋转)

char reflected[19][19];
for (int i = 0; i < n; i++)for (int j = 0; j < n; j++)reflected[i][j] = s[i][n - 1 - j];  // 先水平反射然后尝试对反射后的图案再进行 90/180/270 度旋转,检查是否等于目标图。

🧩 主程序逻辑(流程图)

读取 n 和两个图案 s、t
↓
尝试 change1(旋转 90°)→ 是 → 输出 1
↓
尝试 change2(旋转 180°)→ 是 → 输出 2
↓
尝试 change3(旋转 270°)→ 是 → 输出 3
↓
尝试 change4(反射)→ 是 → 输出 4
↓
尝试 反射+旋转组合 → 是 → 输出 5
↓
s 和 t 完全一致 → 是 → 输出 6
↓
否则 → 输出 7(无法变换)

完整代码

#include <bits/stdc++.h>
using namespace std;char s[19][19], t[19][19], temp[19][19];
int n;bool check(char temp[][19], char t[][19]) // 判断两个 n * n 的图形是否一样
{for (int i = 0; i < n; i++)for (int j = 0; j < n; j++)if (temp[i][j] != t[i][j])return false;return true;
}
bool change1(char s[][19]) /*翻转90度*/
{for (int i = 0; i < n; i++)for (int j = 0; j < n; j++)temp[i][j] = s[n - 1 - j][i];return check(temp, t);
}
bool change2(char s[][19]) /*翻转180度*/
{for (int i = 0; i < n; i++)for (int j = 0; j < n; j++)temp[i][j] = s[n - 1 - i][n - 1 - j];return check(temp, t);
}
bool change3(char s[][19]) /*翻转270度*/
{for (int i = 0; i < n; i++)for (int j = 0; j < n; j++)temp[i][j] = s[j][n - 1 - i];return check(temp, t);
}
bool change4(char s[][19]) /*反射*/
{for (int i = 0; i < n; i++)for (int j = 0; j < n; j++)temp[i][j] = s[i][n - 1 - j];return check(temp, t);
}int main()
{cin >> n;for (int i = 0; i < n; i++) /*转换前*/cin >> s[i];for (int i = 0; i < n; i++) /*转换后*/cin >> t[i];if (change1(s)) // s 翻转 90 度后,看是否和 t 相等{cout << 1;}else if (change2(s)) // s 翻转 180 度后,看是否和 t 相等{cout << 2;}else if (change3(s)) // // s 翻转 270 度后,看是否和 t 相等{cout << 3;}else if (change4(s)) // 反射{cout << 4;}else // 组合{char reflected[19][19];for (int i = 0; i < n; ++i)for (int j = 0; j < n; ++j)reflected[i][j] = s[i][n - 1 - j];if (change1(reflected) || change2(reflected) || change3(reflected)){cout << 5;}else if (check(s, t)){cout << 6;}else{cout << 7;}}return 0;
}

官方思路

  • 数据结构
    用一个 Board 结构体保存图案内容;直接按值传递,可方便地返回新图案。
  • 三个基本操作
    • rotate:返回顺时针旋转 90° 后的棋盘
    • reflect:返回水平翻转后的棋盘
    • eqboard:判断两棋盘是否完全一致
  • 枚举判断顺序
    按 1→2→3→4→5→6→7 的顺序逐一比较,首次匹配即输出对应编号。

3️⃣ 代码逐行详解

int n;              struct Board {      char b[10][10];  
};/* ---------- 旋转 90° ---------- */
Board rotate(Board x) {Board temp;for (int i = 0; i < n; ++i)for (int j = 0; j < n; ++j)temp.b[i][j] = x.b[n - 1 - j][i];return temp;
}/* ---------- 水平翻转 ---------- */
Board reflect(Board x) {Board temp;for (int i = 0; i < n; ++i)for (int j = 0; j < n; ++j)temp.b[i][j] = x.b[i][n - 1 - j];return temp;
}/* ---------- 判断两图是否相等 ---------- */
bool eqboard(Board x, Board y) {for (int i = 0; i < n; ++i)for (int j = 0; j < n; ++j)if (x.b[i][j] != y.b[i][j])return false;return true;
}
int main() 
{Board st, ed;cin >> n;/* 读入起始图案 */for (int i = 0; i < n; ++i)for (int j = 0; j < n; ++j)cin >> st.b[i][j];/* 读入目标图案 */for (int i = 0; i < n; ++i)for (int j = 0; j < n; ++j)cin >> ed.b[i][j];/* ---------- 按优先级逐一比较 ---------- */if (eqboard(ed, rotate(st)))                     cout << 1;else if (eqboard(ed, rotate(rotate(st))))        cout << 2;else if (eqboard(ed, rotate(rotate(rotate(st)))))cout << 3;else if (eqboard(ed, reflect(st)))               cout << 4;else if (eqboard(ed, rotate(reflect(st))) ||eqboard(ed, rotate(rotate(reflect(st)))) ||eqboard(ed, rotate(rotate(rotate(reflect(st)))))) cout << 5;else if (eqboard(ed, st))                        cout << 6;else                                             cout << 7;return 0;
}

判断逻辑说明:

  1. 编号 1∼31 \sim 313:直接对 ststst 连续调用 rotaterotaterotate,分别比较 90°/180°/270°90°/180°/270°90°/180°/270°

  2. 编号 444:比较一次 reflectreflectreflect

  3. 编号 555reflectreflectreflect 后再尝试三种旋转

  4. 写成三次 OROROR 判断最直观,也可使用循环减少代码

  5. 编号 666:若原图与目标图完全一致

  6. 编号 777:上述均不满足则输出 777

完整代码

#include <bits/stdc++.h>
using namespace std;
int n;struct Board
{char b[10][10];
};Board rotate(Board x) // 旋转90度
{Board temp;for (int i = 0; i < n; i++)for (int j = 0; j < n; j++)temp.b[i][j] = x.b[n - 1 - j][i];return temp;
}
Board reflect(Board x) // 水平旋转
{Board temp;for (int i = 0; i < n; i++)for (int j = 0; j < n; j++)temp.b[i][j] = x.b[i][n - 1 - j];return temp;
}
bool eqboard(Board x, Board y)
{for (int i = 0; i < n; i++)for (int j = 0; j < n; j++)if (x.b[i][j] != y.b[i][j])return false;return true;
}
int main()
{Board st, ed;cin >> n;for (int i = 0; i < n; i++)for (int j = 0; j < n; j++)cin >> st.b[i][j];for (int i = 0; i < n; i++)for (int j = 0; j < n; j++)cin >> ed.b[i][j];if (eqboard(ed, rotate(st))){cout << 1;}else if (eqboard(ed, rotate(rotate(st)))){cout << 2;}else if (eqboard(ed, rotate(rotate(rotate(st))))){cout << 3;}else if (eqboard(ed, reflect(st))){cout << 4;}else if (eqboard(ed, rotate(reflect(st))) || eqboard(ed, rotate(rotate(reflect(st)))) || eqboard(ed, rotate(rotate(rotate(reflect(st)))))){cout << 5;}else if (eqboard(ed, st)){cout << 6;}else{cout << 7;}return 0;
}
http://www.xdnf.cn/news/15724.html

相关文章:

  • 如何检查GitHub上可能潜在的信息泄漏
  • Vue3 Anime.js超级炫酷的网页动画库详解
  • NW983NW988美光固态闪存NW991NW992
  • 一个简单的带TTL的LRU的C++实现
  • 《通信原理》学习笔记——第四章
  • IDEA 中 Maven 配置:当前项目与新项目的统一设置方法
  • final 使用
  • oracle 11.2.0.4 RAC下执行root.sh脚本报错
  • leetcode2_135.分发糖果
  • ollma dify 搭建合同审查助手
  • 【Python】一些PEP提案(三):with 语句、yield from、虚拟环境
  • MySQL中的索引和事务
  • vue2 面试题及详细答案150道(81 - 90)
  • 解锁 Java 并发编程的奥秘:《Java 并发编程之美》中的技术亮点与难题攻克
  • FastAdmin后台登录地址变更原理与手动修改方法-后台入口机制原理解析-优雅草卓伊凡
  • 【计算机网络】MAC地址与IP地址:网络通信的双重身份标识
  • TCP通讯开发注意事项及常见问题解析
  • 接口测试的原则、用例与流程详解
  • 百度权重提升技巧分析:从底层逻辑到实战策略
  • 某邮生活旋转验证码识别
  • 函数返回值问题,以及返回值的使用问题(c/c++)
  • 4G模块 A7680发送中文短信到手机
  • 2-大语言模型—理论基础:详解Transformer架构的实现(2)
  • 雾化技术赋能 全鼎如何打造软磁材料护城河
  • 最小生成树算法详解
  • 基于单片机红外感应智能卫生间系统仿真论文
  • 开源Docmost知识库管理工具
  • Web开发 02
  • MariaDB 10.4.34 安装配置文档(Windows 版)
  • ChatGPT Agent:统一端到端Agentic模型的技术革新与行业影响