[R19A]特殊卡片


数据规模:2≤n≤10002 \le n \le 1000,保证 aa 是 11 到 nn 的排列(每个数字恰好出现一次)。

思路

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

由于输入保证是 11 到 nn 的一个排列(即数组下标集合 {1,…,n}\{1,\dots,n\} 到数值集合 {1,…,n}\{1,\dots,n\} 的双射),ai=ja_i = j 中的 jj 被 aia_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() {
    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)
}