第一种方法:

暴力枚举

dai码

#include<bits/stdc++.h>
using namespace std;
long long n,m,l;
int a[100000],s[100000],d[100000],ans;
int main()
{
    cin>>n;
    for(int i=0;i<n;i++)
    {
        cin>>a[i];
        if(i==a[i])
        {
            s[i]=1;
            ans++;
        }
    }
    int q=0;
    for(int i=1;i<=n;i++)
    {
        for(int j=1+i;j<=n;j++)
        {
            if(!s[i]&&!s[j])
            {
                if(a[i]==j)
                {
                    q=max(q,1);
                }
                if(a[j]==i)
                {
                    q=max(q,1);
                }
                if(a[j]==i&&a[i]==j)q=2;
            } 
        } 
    }
    ans+=q;
    cout<<ans;
    return 0;
}

然后你会发现:

没错它T了。

于是第二种方法诞生了:

暴力枚举的复杂度是$O(n^2)$,明显行不通。

那么我们为什么要去找$j$呢?

我们直接用$a_i$去找$a_{a_i}$不就好了?

正确的代码

#include<bits/stdc++.h>
using namespace std;
long long n,m,l;
int a[100000],s[100000],d[100000],ans;
int main()
{
    cin>>n;
    for(int i=0;i<n;i++)//因为是从零开始数,所以下标是0
    {
        cin>>a[i];
        if(i==a[i])//如果i=a[i],则标记并ans+1
        {
            s[i]=1;
            ans++;
        }
    }
    int q=0;
    for(int i=1;i<=n;i++)
    {
        if(!s[i]&&!s[a[i]])//如果第i和第a[i]个数没被标记
        {
            if(a[a[i]]==i)q=2;//如果第a[i]个数的值等于i则代表互换ans+2,否则ans+1
            else q=max(q,1);//防止q=2被覆盖
        }
    }
    ans+=q;\\因为只能换一次所以取q最大值
    cout<<ans;
   return 0;
}