求将n个互异的正整数变成上升序列时的最少交换次数

探讨了如何计算通过交换元素使序列变为升序所需的最小交换次数,给出了一种算法思路及实现程序。

问题:有n个互异的正整数,定义将任意两个数的位置进行交换称为一次操作。求将n个数变成上升序列时的最少操作数。

 

       当n=11时,有序列8 3 9 1 5 6 11 4 7 10 2,现在要把它通过交换变成上升序列1 2 3 4 5 6 7 8 9 10 11。可以看出,'8'应该放在第8个位置,而在第8个位置的'4'应该被交换到第4个位置,而在第4个位置的‘1’应该被交换到第1个位置,而此时在第1个位置的正是一开始就拿来交换的数字'8',也就是说,数字'8' '4' '1'形成了一个循环圈,交换2次(8-4,4-1),则数字‘1’‘4’‘8’都能到达最终位置了,在之后的交换中不会在用到这3个数字。同理,对序列的其他数字也如此处理,可以得出其余4个循环圈,(3 9 7 11 2),(5),(6),(10)。那么,最少交换次数 = (3-1)+(5-1) +(1-1) +(1-1)+(1-1) = 6

       假设n个数分成k个“循环圈”,每个“循环圈”的个数分别是a1,a2,……,ak,那么最少交换次数 = (a1-1)+(a2-1)+……+(ak-1) = (a1+a2+……+ak) - 1 * k = n - k

因此,最少交换次数 = 序列个数 - “循环圈”个数

 

本文参考http://blog.youkuaiyun.com/wangxugangzy05/article/details/42454111

 

参考程序:

 

#include<stdio.h>
#include<string.h>
#define maxn 10001

int a[maxn];
int n;

void init()
{
	scanf("%d", &n);
	for(int i = 1; i <= n; i++)
		scanf("%d", &a[i]);
}

void jishu_sort(int a[], int n, int sa[], int rank[])
{
	int count[maxn];
	memset(count, 0, sizeof(count));
	int i;
	for(i = 1; i <= n; i++)
		count[a[i]]++;

	for(i = 1; i < maxn; i++)
		count[i] += count[i-1];

	for(i = 1; i <= n; i++)
	{
		rank[i] = count[a[i]]--;
	}

	for(i = 1; i <= n; i++)
		sa[rank[i]] = a[i];
}

void solve()
{
	int sa[maxn]; //sa[i]表示排第i的是谁
	int rank[maxn]; //rank[i]表示第i个排第几
	memset(sa, 0, sizeof(sa));
	memset(rank, 0, sizeof(rank));

	jishu_sort(a, n, sa, rank); //用计数排序对a数组进行升序排序

	int sign[maxn]; //sign[i]表示第i个数属于第几个“循环圈”
	memset(sign, 0, sizeof(sign));	
	int circle = 0;
	for(int i = 1; i <= n; i++)
		if(!sign[i])
		{
			sign[i] = ++circle;
			int x = sa[rank[i]];
			while(!sign[x])	//找出这个循环圈的其他数字,并写上编号
			{
				sign[x] = circle; //写号
				x = sa[rank[x]];  //找下一个
			}
		}

	//output answer
	printf("%d\n", n - circle);
}

int main()
{
	init();
	solve();
	return 0;
}

 

 

 

 

 

<think>我们讨论的是任意正整数的唯一分解形式,这通常指的是算术基本定理(FundamentalTheoremofArithmetic),即每个大于1的自然数都可以唯一地分解为素数的乘积。因此,搜索词可以是:“arithmeticfundamentaltheorem”或“uniquefactorizationofintegers”或“primefactorizationunique”通过搜索,我们得到算术基本定理的标准表述。回答组织:1.算术基本定理的陈述:每个大于1的整数都可以唯一地表示为素数的乘积(不考虑素数因子的顺序)。2.该唯一性的含义:即若有两种素因子分解,则分解中素数按非递减顺序排列后,对应的素数和指数完全相同。3.补充说明:对于1,它不是素数,且1的素数分解定义为空积(即没有素数因子的乘积)。4.给出一个例子。5.可能提及该定理的证明思路(简要)。根据要,生成相关问题部分,需要至少3个相关问题。注意:公式中,我们用指数形式表示素数分解:$n=p_1^{e_1}p_2^{e_2}\cdotsp_k^{e_k}$,其中$p_i$是素数,$e_i$是正整数指数。由于用户要的是唯一分解形式,我们重点在算术基本定理。</think> ### 任意正整数的唯一分解形式(算术基本定理) 每个大于1的正整数$n$都可以**唯一表示**为素数的乘积,称为**素因数分解**。数学定义为: $$n = p_1^{k_1} \times p_2^{k_2} \times \cdots \times p_m^{k_m}$$ 其中: - $p_1 < p_2 < \cdots < p_m$ 是互异的素数 - $k_1, k_2, \cdots, k_m$ 是正整数指数 此分解的唯一性是指:若有两种素因数分解形式,则素数集合$\{p_i\}$及其指数$\{k_i\}$必定完全相同(不计顺序)。 #### 关键特性 1. **存在性证明** 数学归纳法:若$n$是素数则成立;若$n$是合数,则存在素数因子$p$,使$n = p \times q$($q < n$),由归纳假设$q$可分解为素数乘积。 2. **唯一性证明** 假设存在两种分解$n = p_1 \cdots p_k = q_1 \cdots q_s$。根据Euclid引理,素数$p_1$必整除某个$q_j$,因$q_j$是素数故$p_1 = q_j$。重复此过程可得所有素数对应相等。 #### 示例分解 - $84 = 2^2 \times 3^1 \times 7^1$ - $100 = 2^2 \times 5^2$ - $17 = 17^1$(素数分解) #### 特殊说明 - $1$的特例:定义为**空乘积**(无素数因子) - 实际计算代码(Python): ```python def prime_factors(n): factors = {} d = 2 while n > 1: while n % d == 0: factors[d] = factors.get(d, 0) + 1 n //= d d += 1 return factors print(prime_factors(84)) # 输出: {2: 2, 3: 1, 7: 1} ```
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值