牛客-交换(思维)

牛客-交换(思维)_第1张图片

思路:我们可以推断出有一个循环节,就可以少交换一次,因为n个元素的循环节,只需交换n-1次即可有序。那么对于整个序列来说,最少交换次数为 元素总数-循环节个数。

#include 
#include 
#include 
#include 
#include
using namespace std;
typedef long long ll;
#define space putchar(' ')
#define enter putchar('\n')
typedef pair<int ,int> PII;
const int mod=1e4+7;
const int N=1e5+10;
const int inf=0x7f7f7f7f;


  ll gcd(ll a,ll b){ return b==0?a:gcd(b,a%b); }

ll lcm(ll a,ll b)
{
    return a*(b/gcd(a,b));
}

template <class T>
void read(T &x){
    char c;
    bool op = 0;
    while(c = getchar(), c < '0' || c > '9')
	if(c == '-') op = 1;
    x = c - '0';
    while(c = getchar(), c >= '0' && c <= '9')
	x = x * 10 + c - '0';
    if(op) x = -x;
}
template <class T>
void write(T x){
    if(x < 0) x = -x, putchar('-');
    if(x >= 10) write(x / 10);
    putchar('0' + x % 10);
}
int a[N];
int b[N];
map<int,int> mp;
int vis[N];

int main()
{
    int n;
    read(n);
    for(int i=1;i<=n;i++)
    {
        read(a[i]);
        b[i]=a[i];
    }
    sort(b+1,b+1+n);
    for(int i=1;i<=n;i++)
    {
        mp[b[i]]=i;
    }
    int ans=0;
    for(int i=1;i<=n;i++)
    {

        if(!vis[i])
        {
            //cout<
            int j=i;
            while(!vis[j])
            {
                vis[j]=1;
                j=mp[a[j]];

            }
            ans++;
        }
    }
    write(n-ans);


    return 0;
}








你可能感兴趣的:(牛客)