您的位置:首页 > 教育 > 锐评 > 构造+模拟,CF1148C. Crazy Diamond

构造+模拟,CF1148C. Crazy Diamond

2024/10/6 14:34:03 来源:https://blog.csdn.net/EQUINOX1/article/details/139307937  浏览:    关键词:构造+模拟,CF1148C. Crazy Diamond

一、题目

1、题目描述

2、输入输出

2.1输入

2.2输出

3、原题链接

Problem - 1148C - Codeforces


二、解题报告

1、思路分析

题目提示O(5n)的解法了,事实上我们O(3n)就能解决,关键在于1,n的处理

我们读入数据a[],代表初始数组,p[i]代表 i 的下标

如果p[i] != i

说明需要交换

a[p[i]] 一定能跟a[1]或者a[n]交换, a[i]也一定能跟1或n交换

假设 a[i]  的可交换位置为x,a[p[i]] 的可交换位置为y(x、y只可能为1、n)

那么我们使得元素i从p[i] -> y -> x -> i 就在3步之内让i到达了下标i

此时a[1] 和 a[n]可能不满足a[1] = 1, a[n] = n

事实上我们将每个元素调整完后再调整1和n即可

这也是为什么能从O(5n)优化到O(3n)

 

2、复杂度

时间复杂度: O(3n)空间复杂度:O(n)

3、代码详解

#include <bits/stdc++.h>
using PII = std::pair<int, int>;
const int N = 3e5 + 10;
int p[N], a[N], n, s;
std::vector<PII> path;void swap(int x, int y) {std::swap(p[a[x]], p[a[y]]);std::swap(a[x], a[y]);path.emplace_back(x, y);
}int main () {std::cin >> n;path.reserve(5 * n);for (int i = 1; i <= n; i ++ ) std::cin >> a[i], p[a[i]] = i;for (int i = 1; i <= n / 2; i ++ ) {if (p[i] != i) {if (p[i] <= n / 2) {swap(p[i], n);swap(i, n);}else {swap(1, p[i]);swap(1, n);swap(i, n);}}}for (int i = n / 2 + 1; i <= n; i ++ ) {if (p[i] != i) {if (p[i] > n / 2) {swap(1, p[i]);swap(1, i);}else {swap(p[i], n);swap(1, n);swap(1, i);}}}if (a[1] != 1) swap(1, n);std::cout << path.size() << '\n';for (auto [x, y] : path) std::cout << x << " " << y << '\n';return 0;
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com