zoukankan      html  css  js  c++  java
  • 【2018黑龙江省赛】UPC-7224 The puzzle(任意两数交换排序次数)

    题目描述
    Kayaking is playing a puzzle game containing n different blocks. He marks the blocks with integers from 1 to n, which show the blocks’ original positions. Each time he can exchange two blocks and he wants to know how many times he needs at least to restore the puzzle.

    输入
    The input starts with one line contains exactly one positive integer T which is the number of test cases.
    Each test case contains two lines.
    The first line contains an integer, which indicates the number of puzzle pieces.
    The second line contains n different integers, the i-th number means the mark of the block in the i-th position.

    输出
    For each test case, output one line with one number represents the minimum operations.

    样例输入
    2
    4
    2 3 4 1
    4
    2 1 4 3

    样例输出
    3
    2

    提示
    1≤T≤20,1≤n≤100000
    题意: 给出一个序列,一个操作,选择任意两个数做一次位置交换,需要交换几次使之有序。

    题解: 如果是相邻两数交换那很明显就是个求逆序数的题,而这里是任意两数交换,可以知道,每个数都是唯一的,那么每个数都有自己的位置,他们经过一些两两交换后导致无序,也就是给出的序列的模样。那么将这个过程逆回去暴力模拟,就可以得到有序序列,两两交换是在一些数范围内的,也就是说交换的操作肯定会出现环,那么其实就是每个数找打自己改在的位置,然后看自己该在的位置的数是谁,再去找那个数改在的位置,这样不断迭代会找到一个环,这个环中数的个数-1就是交换次数,找到几个这样的环然后计数,输出结果即可。

    #include<bits/stdc++.h>///任意两数交换,那就找循环节,因为数都是唯一的,那么找到每一个数应该在的位置,任何不在自己位置的数都是要交换的环中的,直接暴力找,计数即可
    #define LL long long
    #define M(a,b) memset(a,b,sizeof a)
    #define pb(x) push_back
    using namespace std;
    const int maxn=1e5+7;
    int a[maxn];
    bool vis[maxn];
    int main()
    {
        int t,n;
        scanf("%d",&t);
        while(t--)
        {
            M(vis,false);
            scanf("%d",&n);
            for(int i=1;i<=n;i++)
                scanf("%d",&a[i]);
            LL ans=0;
            for(int i=1;i<=n;i++)
            {
                int cnt=0;
                int tmp=i;
                while(!vis[tmp]&&a[tmp]!=tmp)///找下一个自己该在的位置
                {
                    cnt++;
                    vis[tmp]=true;///标记环中该值是否被遍历过
                    tmp=a[tmp];
                }
                if(cnt) ans+=cnt-1;///每个环的交换次数求和
            }
            printf("%lld
    ",ans);
        }
    }
    
    
  • 相关阅读:
    搭建自己的博客(九):使用shell模式批量添加博客文章并增加分页功能
    搭建自己的博客(八):使用fontawesome框架来添加图标以及美化详情页
    linux系列(十):cat命令
    linux系列(九):touch命令
    搭建自己的博客(七):使用bootstrap框架美化导航栏
    linux系列(八):cp命令
    搭建自己的博客(六):添加首页,使用css对界面做美化
    linux系列(七):mv命令
    Re-enable extensions not coming from Chrome Web Store on Chrome v35+ (with enhanced security)
    liblensfun 在 mingw 上编译时遇到的奇怪问题
  • 原文地址:https://www.cnblogs.com/kuronekonano/p/11135702.html
Copyright © 2011-2022 走看看