Codeforces Round 903 (Div. 3)C题perfect square

题源:Codeforces Round 903 (Div. 3)D题

题目

title

输入输出范例
输入:

5
4
abba
bcbb
bccb
abba
2
ab
ba
6
codefo
rcesco
deforc
escode
forces
codefo
4
baaa
abba
baba
baab
4
bbaa
abba
aaba
abba

题意解析

可以把每一个图形都分成四部分,只有一个部分是元始天尊,其他的都是由这个部分,围绕那个虚无的中心点旋转而生成的。
这样看来元始天尊的每一个字母通过旋转可以到达另外三个字母的位置,因此元始天尊那部分的每一个字母背后实际上都有四个位置。
因此问题就简化成了遍历元始天尊的每一个字母的四个位置,并取出四个位置上的字母最大值然后计算把这四个位置上的字母全部变成这个字母需要多少步。

代码总结

这里涉及到了 n ∗ n 方阵内元素的旋转问题,可以总结一下。令 这个 n ∗ n 方阵的二维数组是 a [ n ] [ n ] 那么,如果 a [ i ] [ j ] 如果是按 照顺时针方向旋转四次回到原位置,他的四个位置分别是: a [ i ] [ j ] , a [ j ] [ n − 1 − i ] , a [ n − 1 − i ] [ n − 1 − j ] , a [ n − 1 − j ] [ i ] 如果他是逆时针旋转 4 次回到原位置,他的四个位置分别是: a [ i ] [ j ] , a [ n − 1 − j ] [ i ] , a [ n − 1 − i ] [ n − 1 − j ] , a [ j ] [ n − 1 − i ] 简单的进行一个总结,令对于 i 或者 j 进行 n − 1 − i / n − 1 − j 的操作称为 f ( i ) 或 f ( j ) ,那么顺时针就是不断地 x = y , y = f ( x ) 逆时针就是不断地进行 y = x , x = f ( y ) 操作,适用于任意 n 这里涉及到了n*n方阵内元素的旋转问题,可以总结一下。令\\这个n*n方阵的二维数组是a[n][n]那么,如果a[i][j]如果是按\\照顺时针方向旋转四次回到原位置,他的四个位置分别是:\\a[i][j],a[j][n-1-i],a[n-1-i][n-1-j],a[n-1-j][i]\\如果他是逆时针旋转4次回到原位置,他的四个位置分别是:\\a[i][j],a[n-1-j][i],a[n-1-i][n-1-j],a[j][n-1-i]\\简单的进行一个总结,令对于i或者j进行n-1-i/n-1-j\\的操作称为f(i)或f(j),那么顺时针就是不断地x=y,y=f(x)\\逆时针就是不断地进行y=x,x=f(y)操作,适用于任意n 这里涉及到了nn方阵内元素的旋转问题,可以总结一下。令这个nn方阵的二维数组是a[n][n]那么,如果a[i][j]如果是按照顺时针方向旋转四次回到原位置,他的四个位置分别是:a[i][j]a[j][n1i]a[n1i][n1j]a[n1j][i]如果他是逆时针旋转4次回到原位置,他的四个位置分别是:a[i][j]a[n1j][i]a[n1i][n1j]a[j][n1i]简单的进行一个总结,令对于i或者j进行n1i/n1j的操作称为f(i)f(j),那么顺时针就是不断地x=y,y=f(x)逆时针就是不断地进行y=x,x=f(y)操作,适用于任意n

代码展示与分析

这里借用一下jiangly的代码,代码非常清晰干脆

#include <bits/stdc++.h>
using i64 = long long;
void solve() {
    int n;
    std::cin >> n;
    std::vector<std::string> s(n);
    for (int i = 0; i < n; i++) {
        std::cin >> s[i];
    }
    
    int ans = 0;
    for (int i = 0; i < n / 2; i++) {
        for (int j = 0; j < n / 2; j++) {
            int sum = s[i][j] + s[j][n - 1 - i] + s[n - 1 - i][n - 1 - j] + s[n - 1 - j][i];
            int max = std::max({s[i][j], s[j][n - 1 - i], s[n - 1 - i][n - 1 - j], s[n - 1 - j][i]});
            ans += max * 4 - sum;
        }
    }
    std::cout << ans << "\n";
}

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    
    int t;
    std::cin >> t;
    
    while (t--) {
        solve();
    }
    
    return 0;
}

关键代码部分解析

    for (int i = 0; i < n / 2; i++) {
        for (int j = 0; j < n / 2; j++) {
            int sum = s[i][j] + s[j][n - 1 - i] + s[n - 1 - i][n - 1 - j] + s[n - 1 - j][i];
            int max = std::max({s[i][j], s[j][n - 1 - i], s[n - 1 - i][n - 1 - j], s[n - 1 - j][i]});
            ans += max * 4 - sum;
        }
    }
    std::cout << ans << "\n";

这一部分两层 f o r 循环就是遍历了 n ∗ n 方阵左上角 ( i 与 j 均 < n 2 ) 的部分的每一个元素,然后针对这些字母访问他们其他的所有 位置的字母大小,同时计算出如果想要统一,需要操作的次数 这一部分两层for循环就是遍历了n*n方阵左上角(i与j均<\frac{n}2)\\的部分的每一个元素,然后针对这些字母访问他们其他的所有\\位置的字母大小,同时计算出如果想要统一,需要操作的次数 这一部分两层for循环就是遍历了nn方阵左上角(ij<2n)的部分的每一个元素,然后针对这些字母访问他们其他的所有位置的字母大小,同时计算出如果想要统一,需要操作的次数

重要的事情再讲一遍

这个结论还是很不错的
这里涉及到了 n ∗ n 方阵内元素的旋转问题,可以总结一下。令 这个 n ∗ n 方阵的二维数组是 a [ n ] [ n ] 那么,如果 a [ i ] [ j ] 如果是按 照顺时针方向旋转四次回到原位置,他的四个位置分别是: a [ i ] [ j ] , a [ j ] [ n − 1 − i ] , a [ n − 1 − i ] [ n − 1 − j ] , a [ n − 1 − j ] [ i ] 如果他是逆时针旋转 4 次回到原位置,他的四个位置分别是: a [ i ] [ j ] , a [ n − 1 − j ] [ i ] , a [ n − 1 − i ] [ n − 1 − j ] , a [ j ] [ n − 1 − i ] 简单的进行一个总结,令对于 i 或者 j 进行 n − 1 − i / n − 1 − j 的操作称为 f ( i ) 或 f ( j ) ,那么顺时针就是不断地 x = y , y = f ( x ) 逆时针就是不断地进行 y = x , x = f ( y ) 操作,适用于任意 n 这里涉及到了n*n方阵内元素的旋转问题,可以总结一下。令\\这个n*n方阵的二维数组是a[n][n]那么,如果a[i][j]如果是按\\照顺时针方向旋转四次回到原位置,他的四个位置分别是:\\a[i][j],a[j][n-1-i],a[n-1-i][n-1-j],a[n-1-j][i]\\如果他是逆时针旋转4次回到原位置,他的四个位置分别是:\\a[i][j],a[n-1-j][i],a[n-1-i][n-1-j],a[j][n-1-i]\\简单的进行一个总结,令对于i或者j进行n-1-i/n-1-j\\的操作称为f(i)或f(j),那么顺时针就是不断地x=y,y=f(x)\\逆时针就是不断地进行y=x,x=f(y)操作,适用于任意n 这里涉及到了nn方阵内元素的旋转问题,可以总结一下。令这个nn方阵的二维数组是a[n][n]那么,如果a[i][j]如果是按照顺时针方向旋转四次回到原位置,他的四个位置分别是:a[i][j]a[j][n1i]a[n1i][n1j]a[n1j][i]如果他是逆时针旋转4次回到原位置,他的四个位置分别是:a[i][j]a[n1j][i]a[n1i][n1j]a[j][n1i]简单的进行一个总结,令对于i或者j进行n1i/n1j的操作称为f(i)f(j),那么顺时针就是不断地x=y,y=f(x)逆时针就是不断地进行y=x,x=f(y)操作,适用于任意n

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Codeforces Round 894 (Div. 3) 是一个Codeforces举办的比赛,是第894轮的Div. 3级别比赛。它包含了一系列目,其中包括目E. Kolya and Movie Theatre。 根据目描述,E. Kolya and Movie Theatre问要求我们给定两个字符串,通过三种操作来让字符串a等于字符串b。这三种操作分别为:交换a中相同位置的字符、交换a中对称位置的字符、交换b中对称位置的字符。我们需要先进行一次预处理,替换a中的字符,然后进行上述三种操作,最终得到a等于b的结果。我们需要计算预处理操作的次数。 根据引用的讨论,当且仅当b[i]==b[n-i-1]时,如果a[i]!=a[n-i-1],需要进行一次操作;否则不需要操作。所以我们可以遍历字符串b的前半部分,判断对应位置的字符是否与后半部分对称,并统计需要进行操作的次数。 以上就是Codeforces Round 894 (Div. 3)的简要说明和目E. Kolya and Movie Theatre的要求。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [Codeforces Round #498 (Div. 3) (A+B+C+D+E+F)](https://blog.csdn.net/qq_46030630/article/details/108804114)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *3* [Codeforces Round 894 (Div. 3)A~E解](https://blog.csdn.net/gyeolhada/article/details/132491891)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值