贪心算法patA1067Sort with Swap(0, i)

该博客探讨了一种针对数组排序问题的优化算法,通过仅使用swap(0, i)操作来寻找使数组升序排列所需的最小交换次数。作者首先介绍了问题背景,然后详细阐述了算法思路,包括利用数组保存数字顺序,用数字位置替换数字,以及通过变量跟踪已排序部分。在解决过程中,作者经历了超时问题并逐步优化,减少了查找和判断的时间复杂度,最终实现了高效解决方案。
摘要由CSDN通过智能技术生成

题目大意:
只有swap(0,*)的操作,寻找排序到递增的最小的交换次数
输入:n=10
代表0-9这几个数字
题目思路:
1.利用数组保存输入的数据顺序;
2.
0对应的位置是几,和这个数字进行交换
若a[0]的值是0,则找到第一个不匹配的位置与0交换
终止条件为排序完成 (思路正确,但是代码实现比较复杂)

提交:
1.第一次提交超时,因为排序完成的判断每次都是循环全部,可以在查找第一个不匹配的位置时候判断是否排序完毕
2.观看算法笔记,对于数字的查找,可以直接从有序数字后面开始,节省时间
再次查看算法笔记,数组保存的是该数字的位置,这样数组0代表的就是0的位置,0存储在哪里,可以省去查找0的代码
用变量k保存已经有序的位置,i到n,则代表全部有序,代表退出循环
如果a[0]不是0则替换0和在0这个位置上的数字

收获
1.可以用数字保存数字下标i对应的这个数的位置,可以省去查找这个数的时间
2.可以用k保留目前已经有序的位置,防止一直从头开始检测

#include <iostream>
#include<string>
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<vector>
//Be Unique permutation置换 
//Sort with Swap(0, i)
/*
题目大意:
 只有swap(0,*)的操作,寻找排序到递增的最小的交换次数 
 输入:n=10
 代表0-9这几个数字 
题目思路:
 1.利用数组保存输入的数据顺序;
 2.
  0对应的位置是几,和这个数字进行交换
  若a[0]的值是0,则找到第一个不匹配的位置与0交换 
 终止条件为排序完成 
 
提交:
1.第一次提交超时,因为排序完成的判断每次都是循环全部,可以在查找第一个不匹配的位置时候判断是否排序完毕 
2.观看算法笔记,对于数字的查找,可以直接从有序数字后面开始,节省时间 
再次查看算法笔记,数组保存的是该数字的位置,这样数组0代表的就是0的位置,0存储在哪里,可以省去查找0的代码
用变量k保存已经有序的位置,i到n,则代表全部有序,代表退出循环 
如果a[0]不是0则替换0和在0这个位置上的数字 
*/
int find(int *a,int k,int n,int b)
{
	for(int i=k;i<n;i++)
	{
		if(a[i]==b)
		return i;
	}
}

using namespace std;
int main() {
    
   int n;
   cin>>n;
   int *a=(int *)malloc(sizeof(int)*n);
   for(int i=0;i<n;i++)
   {
     int input;
	 cin>>input;
	 a[input]=i;//数组下标表示那个数字,i代表这个数字现在在哪里  
 	}; 
 	int sum=0;
	int k=1;
	while(1)
	{
		if(a[0]!=0)
		{
			swap(a[0],a[a[0]]);
			sum++;
		 } 
		 else
		 {
		 	int i;
		 	for(i=k;i<n;i++)
		 	{
		 		if(a[i]!=i)
		 		{
		 			k=i;
		 			swap(a[0],a[i]);
		 			sum++;
		 			break;
				 }
			 }
			 if(i==n)break;
		 }
		/* for(int i=0;i<n;i++)
		 cout<<a[i]<<" ";*/
		 //cout<<endl;
	 } 
   
   cout<<sum<<endl;
   
   
   
   
   
   
    /*int n;
	cin>>n;
	int *a =(int *)malloc(sizeof(int)*n);
	for(int i=0;i<n;i++)
	{
		scanf("%d",&a[i]);
	}
	int sum=0;
	
	bool right=false;
	int first=0;
	while(right==false)
	{	int k=find(a,0,n,0);//查找0的位置 
		int h=find(a,0,n,k);//查找0对应数字的位置 
		if(k==0)
		{
			int j;
			for( j=1;j<n;j++)
			{
				if(a[j]!=j)
				{
					swap(a[0],a[j]);
					first=j;
				    break;
				}
			}
			if(j==n)
			{
				right=true;
				break; 
			}
		 } 
		 else
		swap_a(&a[k],&a[h]); 
		
		sum++;
	}
	cout<<sum<<endl;*/
	system("pause");
	
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值