[R19A]特殊卡片


数据规模:2n10002 \le n \le 1000,保证 aa11nn 的排列(每个数字恰好出现一次)。

思路

ii 张卡片是特殊卡片,当且仅当存在某个 jj 满足 ai=ja_i = jaj=ia_j = i

由于输入保证是 11nn 的一个排列(即数组下标集合 {1,,n}\{1,\dots,n\} 到数值集合 {1,,n}\{1,\dots,n\} 的双射),ai=ja_i = j 中的 jjaia_i 唯一确定:j=aij = a_i。于是「存在 jj」这个条件不用枚举,直接看 j=aij = a_i 是否满足 aj=ia_j = i 即可。

也就是说,第 ii 张卡片特殊当且仅当

aai=i.a_{a_i} = i.

逐位判断即可。注意题目中卡片下标从 11 开始,代码里数组下标从 00 开始,要做相应偏移。

复杂度

时间 O(n)O(n),空间 O(n)O(n)

仓颉实现

import std.env.*
import std.convert.*

main(): Int64 {
    let reader = getStdIn()
    let n = Int64.parse(reader.readln().getOrThrow())
    let a = reader.readln().getOrThrow().split(" ", removeEmpty: true).map({ p: String => Int64.parse(p) })
    var cnt = 0
    var i = Int64(0)
    while (i < n) {
        // 第 (i+1) 张卡片上的数字是 a[i];条件 a_{a_{i+1}} == i+1
        if (a[a[i] - 1] == i + 1) {
            cnt++
        }
        i++
    }
    println(cnt)
    return 0
}