1067 Sort with Swap(0, i)

Given any permutation of the numbers {0, 1, 2,…, N−1}, it is easy to sort them in increasing order. But what if Swap(0, *) is the ONLY operation that is allowed to use? For example, to sort {4, 0, 2, 1, 3} we may apply the swap operations in the following way:

Swap(0, 1) => {4, 1, 2, 0, 3}
Swap(0, 3) => {4, 1, 2, 3, 0}
Swap(0, 4) => {0, 1, 2, 3, 4}
Now you are asked to find the minimum number of swaps need to sort the given permutation of the first N nonnegative integers.

Input Specification:
Each input file contains one test case, which gives a positive N (≤10
​5
​​ ) followed by a permutation sequence of {0, 1, …, N−1}. All the numbers in a line are separated by a space.

Output Specification:
For each case, simply print in a line the minimum number of swaps need to sort the given permutation.

Sample Input:
10
3 5 7 2 6 4 9 0 8 1
Sample Output:
9

思路
要想换的次数最少,就必须尽量保证每次换的时候都把至少一个元素换到正确位置。既然只能交换(0,*),那我们就把0位置上的元素直接放到他应该在的位置就好了。光有这一个判断还不够,如果出现类似0 4 2 1 3的情况,也就是0号元素已就位该怎么办。

那我们此时只能进行一次看似多余但并不多余的交换。就是找到0号位置后面第一个还未就位的数字。比如要想把4就位,就必须swap(0,1) 然后再重复上面黑体字的操作。

如果仅仅做到这些还并不能得满分,线性找0号位后面的未就位数字是会超时的,我们应该想个办法。详见代码。

#include<bits/stdc++.h>
#define maxn 100001
using namespace std;
int n,cnt;
int data[maxn];
void swap(int i,int j){
	cnt++;
	int tmp;
	tmp=data[i];
	data[i]=data[j];
	data[j]=tmp;
}

int main(){
	set<int>st;//用于存放还未就位的数的下标
	scanf("%d",&n);
	for(int i=0;i<n;i++){
		scanf("%d",&data[i]);
		if(data[i]!=i&&i!=0)//0位置不能存
			st.insert(i);
	}
	int idx;
	while(!st.empty()){
		if(data[0]!=0){
			st.erase(data[0]);//一定要先删除再交换,原因很简单自己想
			swap(0,data[0]);
		}
		else{
			idx=*st.begin();
			st.erase(idx);
			swap(0,idx);
			st.insert(idx);//进行这次多余交换后,idx位置就成为了未就位的位置,应当重新插入set中
		}
	}
	printf("%d",cnt);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
牙科就诊管理系统利用当下成熟完善的SSM框架,使用跨平台的可开发大型商业网站的Java语言,以及最受欢迎的RDBMS应用软件之一的Mysql数据库进行程序开发。实现了用户在线查看数据。管理员管理病例管理、字典管理、公告管理、药单管理、药品管理、药品收藏管理、药品评价管理、药品订单管理、牙医管理、牙医收藏管理、牙医评价管理、牙医挂号管理、用户管理、管理员管理等功能。牙科就诊管理系统的开发根据操作人员需要设计的界面简洁美观,在功能模块布局上跟同类型网站保持一致,程序在实现基本要求功能时,也为数据信息面临的安全问题提供了一些实用的解决方案。可以说该程序在帮助管理者高效率地处理工作事务的同时,也实现了数据信息的整体化,规范化与自动化。 管理员在后台主要管理病例管理、字典管理、公告管理、药单管理、药品管理、药品收藏管理、药品评价管理、药品订单管理、牙医管理、牙医收藏管理、牙医评价管理、牙医挂号管理、用户管理、管理员管理等。 牙医列表页面,此页面提供给管理员的功能有:查看牙医、新增牙医、修改牙医、删除牙医等。公告信息管理页面提供的功能操作有:新增公告,修改公告,删除公告操作。公告类型管理页面显示所有公告类型,在此页面既可以让管理员添加新的公告信息类型,也能对已有的公告类型信息执行编辑更新,失效的公告类型信息也能让管理员快速删除。药品管理页面,此页面提供给管理员的功能有:新增药品,修改药品,删除药品。药品类型管理页面,此页面提供给管理员的功能有:新增药品类型,修改药品类型,删除药品类型。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值