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

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.dtcms.com/a/286327.html

相关文章:

  • 《通信原理》学习笔记——第四章
  • 【论文阅读】BEVFusion: A Simple and Robust LiDAR-Camera Fusion Framework
  • Redis——BigKey
  • Radix-4 Booth乘法器计算步骤
  • 【AI论文】CLiFT:面向计算高效与自适应神经渲染的压缩光场标记
  • vue2 面试题及详细答案150道(41 - 60)
  • Node.js链接MySql
  • Vue常见指令
  • Java大厂面试实录:从Spring Boot到AI微服务架构的深度解析
  • 深度学习零基础入门(3)-图像与神经网络
  • UE5 一些关于过场动画sequencer,轨道track的一些Python操作
  • 力扣347:前K个高频元素
  • 科技照亮童心|激光院与跳伞塔社区开展公益活动
  • Day24| 93.复原IP地址、78.子集、90.子集II
  • NIO简单介绍和运用
  • MySQL计数函数count原理分析
  • 深入理解Linux文件I/O:系统调用与标志位应用
  • 区块链加密技术全景解析
  • 高效VLP蛋白表达|病毒样颗粒生产|疫苗研发平台
  • 【无标题】标准模型粒子行为与11维拓扑量子色动力学模型严格对应的全面论述
  • 文献分享0719
  • MyBatis:配置文件完成增删改查_添加
  • 智慧后厨检测算法构建智能厨房防护网
  • 零基础入门:用按键精灵实现视频自动操作(附完整脚本)
  • C语言:数组
  • MySQL的关键日志
  • 洛谷 P1395 会议
  • Logback 配置的利器:深入理解<property>与<variable>
  • 教育行业网络升级最佳实践:SD-WAN、传统方案与混合方案对比分析
  • Android sdk 升级 34到35