蓝桥杯 交换瓶子

有N个瓶子,编号 1 ~ N,放在架子上。
比如有5个瓶子:
2 1 3 5 4
要求每次拿起2个瓶子,交换它们的位置。
经过若干次后,使得瓶子的序号为:
1 2 3 4 5

对于这么简单的情况,显然,至少需要交换2次就可以复位。

如果瓶子更多呢?你可以通过编程来解决。

输入格式为两行:
第一行: 一个正整数N(N<10000), 表示瓶子的数目
第二行:N个正整数,用空格分开,表示瓶子目前的排列情况。


输出数据为一行一个正整数,表示至少交换多少次,才能完成排序。

例如,输入:
5
3 1 2 5 4

程序应该输出:
3

再例如,输入:
5
5 4 3 2 1

程序应该输出:

2

看数据大小,不能让时间复杂度为O(n^2),只能是O(n),那么涉及到了异或运算的一个小技巧

比如a与b两值进行交换,不借助其他变量实现,那么a=a^b;b=a^b;a=a^b;

下面是被人的代码

#include <stdio.h>
#include <math.h>
int arr[10010];
int flag[10010];
int main()
{
    int ans = 0;
    int n,i;
    scanf("%d",&n);
    for(i = 1 ; i <= n ; i ++) scanf("%d",&arr[i]);
  //  for(i = 1 ; i <= n ; i ++) printf("%d ",arr[i]);
   // printf("\n");
    for(i = 1 ; i <= n ; i ++ )flag[arr[i]] = i;
   // for(i = 1 ; i <= n ; i ++) printf("%d ",flag[arr[i]]);
   // printf("\n");

    for(i = 1 ; i <= n ; i ++)
    {
        if( i != arr[i] )
        {
            int x = arr[i];
            arr[i] ^= arr[flag[i]] ^= arr[i] ^= arr[flag[i]];      //如果这个位置的数字与应放入的数字不同,那么就进行交换,与它交换的是它应该放入的位置的数字
            flag[i] ^= flag[x] ^= flag[i] ^= flag[x];	//对应的也要改
            ans ++;
        }
    }
    printf("%d\n",ans);
    return 0;
}

你可能感兴趣的:(蓝桥杯 交换瓶子)