好弱啊,这个题目折腾了好久。

构造hash表用来维护各个元素所在的位置,利用map维护一颗红黑树来保存还未确定的元素的位置。

(1)用0不断的跟其他元素交换,每次交换都会保证一个元素在正确的位置。

(2)交换的过程中可能使得元素0到第0个位置,此时用0与某个还未在正确位置的元素交换。

循环(1)(2)直至所有元素都在正确的位置。

出现(2)这种情况的最大次数可能N,因为出现一次这种情况,一定会在接下来运行(1)的时候保证至少一个元素被交换到正确的位置。综上所述,最大交换次数应该不会高于2*N,每次交换会维护一次map,所以最终的算法复杂度应该为O(NlogN).

// 1067. Sort with Swap.cpp : 定义控制台应用程序的入口点。
//#include "stdafx.h"
#include <iostream>
#include <map>
using namespace std;const int N = 100003;
int a[N], hashTab[N];
map<int, int> cmap; void swap(int &m1, int &m2){int temp = m1;m1 = m2; m2 = temp;
}int main()
{int n, cnt = 0, diff;cin >> n;for(int i = 0; i < n; i++){cin >> a[i];hashTab[a[i]] = i;if(i != 0 && a[i] != i)cmap[i] = i;}do{while(hashTab[0] != 0){swap(a[hashTab[0]], a[hashTab[hashTab[0]]]);int tmp = hashTab[0]; hashTab[0] = hashTab[hashTab[0]];hashTab[tmp] = tmp;map<int, int>::iterator mIte = cmap.find(tmp);cmap.erase(mIte);cnt++;}if(cmap.size() != 0){map<int, int>::iterator mIte = cmap.begin();cnt++;hashTab[0] = hashTab[mIte -> first];hashTab[mIte -> first] = 0;swap(a[hashTab[mIte -> first]], a[0]);}} while(cmap.size() != 0);cout << cnt << endl;return 0;
}

改进版本:

弃用map,维护一个bool数组used[]保存某个元素是否已经确定好,每当一个元素被确定下来,就赋值为true(初始时数组清0)。

设置一个在第2步可以被用来交换的位置swapPos,初始时swapPos=1,由某个元素确定下来,就要询问该位置是否和swapPos相等,如果相等,则相应的swapPos后移直至一个还未确定好的位置pos(即used[pos]==false)。由此观之,swapPos后移顶多后移N个位置,每次在第二步寻找与0交换的元素,可以直接用a[swapPos]与之交换。所以最终的算法复杂度应为O(3*N)。

// 1067. Sort with Swap.cpp : 定义控制台应用程序的入口点。
//#include "stdafx.h"
#include <iostream>
#include <map>
using namespace std;const int N = 100003;
int a[N], hashTab[N];
bool used[N];void swap(int &m1, int &m2){int temp = m1;m1 = m2; m2 = temp;
}int main()
{int n, cnt = 0;cin >> n;memset(used, 0, sizeof(used));for(int i = 0; i < n; i++){cin >> a[i];hashTab[a[i]] = i;if(a[i] == i)used[i] = true;}int swapPos = 1;while(used[swapPos])swapPos++;do{while(hashTab[0] != 0){swap(a[hashTab[0]], a[hashTab[hashTab[0]]]);int tmp = hashTab[0]; hashTab[0] = hashTab[hashTab[0]];hashTab[tmp] = tmp;used[tmp] = true;if(tmp == swapPos){swapPos++;while(used[swapPos])swapPos++;}cnt++;}if(swapPos != n){cnt++;hashTab[0] = hashTab[swapPos];hashTab[swapPos] = 0;swap(a[hashTab[swapPos]], a[0]);}} while(swapPos != n);cout << cnt << endl;return 0;
}

转载于:https://www.cnblogs.com/cjweffort/p/3374804.html

1067. Sort with Swap(0,*)相关推荐

  1. PAT甲级1067 Sort with Swap(0, i):[C++题解]此题不是很懂!!

    文章目录 题目分析 题目来源 题目分析 来源:acwing 分析:y总从图论的角度来讲解的这道题,听得不是很懂. 此题不是很懂,暂留以后探讨.存在鸽的可能. ac代码 #include<bits ...

  2. 1067 Sort with Swap(0, i) (25 分)

    1067 Sort with Swap(0, i) (25 分) Given any permutation of the numbers {0, 1, 2,..., N−1}, it is easy ...

  3. PTA 1067 Sort with Swap(0, i) (25 分)(思维)

    传送门:点我 Given any permutation of the numbers {0, 1, 2,..., N−1}, it is easy to sort them in increasin ...

  4. 【题意+分析】1067 Sort with Swap(0, i) (25 分)_24行代码AC

    立志用最少的代码做最高效的表达 PAT甲级最优题解-->传送门 Given any permutation of the numbers {0, 1, 2,-, N−1}, it is easy ...

  5. 1067 Sort with Swap(0, i) (25 分)【难度: 中 / 知识点: 置换群】

    https://pintia.cn/problem-sets/994805342720868352/problems/994805403651522560 这种相关的题目见过很多次了. 常见的是只可以 ...

  6. PAT A1067 Sort with Swap(0, i) ——天街小雨润如酥,草色遥看近却无

    PAT A1067 Sort with Swap(0, i) 本题使用了姥姥教的方法,通过交换过程(第一个开始动的元素,通过一系列交换到达自己应该在的位置)可以发现他们形成了一个闭环,大家手拉手,每个 ...

  7. 10-排序6 Sort with Swap(0, i) (25 分)

    Given any permutation of the numbers {0, 1, 2,..., N−1}, it is easy to sort them in increasing order ...

  8. 算法 排序6 Sort with Swap(0, i) 2013年免试研究生上机考试真题

    全部每周作业和视频思考题答案和解析 见 浙江大学 数据结构 思考题+每周练习答案 题目:Given any permutation of the numbers {0, 1, 2,..., N−1}, ...

  9. 7-16 Sort with Swap(0, i) | PTA数据结构与算法——C语言实现

    2013年浙江大学免试研究生上机考试真题. 原题链接:PTA | 程序设计类实验辅助教学平台 题目描述 给定包含数字 {0, 1, 2,..., N−1} 的任一排列,很容易对它们进行升序排序. 但是 ...

最新文章

  1. powerbook g4装linux,揭秘:服务器操作系统Linux版本发行
  2. 人工智能起源于这三家学派?
  3. 莫比乌斯函数_莫比乌斯环:python-matplotlib可视化实现
  4. Mysql是否开启binlog日志开启方法
  5. 国家杰出青年入选者分析:北大最多,深大成“黑马”
  6. java实现展示框,如何使用纯CSS实现蝴蝶标本的展示框效果
  7. Flask-login 原理
  8. LeetCode——Maximum Depth of Binary Tree
  9. 论坛指定portal.php,去除Discuz论坛域名后面的/forum.php或portal.php
  10. 【蓝桥杯】历年真题题目及题解汇总
  11. java 生成二维码,带logo,底部文字
  12. SourceOffSite使用方法
  13. PLC不用编程,以太网方式与多台智能仪表、变频器等串口设备通讯(基于智能网关)
  14. 集成editormd支持markdown语法(二)之页面显示及回显
  15. kali-Linux局域网渗透之Win2008
  16. 苏世民,我的经验和教训(一)
  17. 最最喜欢的韩庚……这个资料-----顶了~/(≧▽≦)/~!!!
  18. 庄家高位出货的三种基本手法
  19. 微信授权登录报错40029
  20. 用手机蓝牙锁定计算机,Bluetooth Screen Lock——当你离开时自动锁定Mac电脑

热门文章

  1. Android开发笔记(二十五)assets目录下的文件读取
  2. Android 类库
  3. find命令 文件名后缀
  4. bash功能特性二 命令别名和历史命令
  5. 编译安装NTP时间服务报错
  6. R语言 par()函数
  7. Hibernate初步
  8. java 静态缓存_JAVA缓存的实现
  9. Windows/Linux下获取当前线程的ID号
  10. antd confirm如何隐藏ok按钮_操作系统如何保护重要文件,Windows 7资源管理器设置隐藏文件夹...