2018NOIP普及组

#include <cstdio>

int n, d[100];

bool v[100];

int main( ) {

    scanf("%d", &n);

    for (int i = 0; i < n; ++i) {

        scanf("%d", d + i);

        v[i] = false;

    }

    int cnt = 0;

    for (int i = 0; i < n; ++i) {

        if (!v[i]) {

            for (int j = i; !v[j]; j = d[j]) {

                v[j] = true;

            }

            ++cnt;

        }

    }

    printf("%d\n", cnt);

    return 0;

}

解析

初始化数组d,给数组v赋值为false。

这里可以理解为,数组v是数组d

0123456789
vfalsefalsefalsefalsefalsefalsefalsefalsefalsefalse
d7143259806
  1. 当i= 0时,j=i=0 v[j]=v[0] = false,

    a). v[0]=true; j=d[0]=7

    b). v[j]=v[7]=true j=d[7]=8

    c). v[j]=v[8]=true j=d[8]=0 (v[0]已经为true,不会运行if,构成循环了,即d的0→7→8→0)

    每结束一次if,cnt+1,即cnt=1;

    第一轮结束后,变成

0123456789
vtruefalsefalsefalsefalsefalsefalsetruetruefalse
d7143259806
  1. 开始第二轮,i=1开始。

    a). v[1]=true; j=d[1]=1(和起始值一样了,构成循环了,即d的1→1)

0123456789
vtruetruefalsefalsefalsefalsefalsetruetruefalse
d7143259806

每结束一次if,cnt+1,即cnt=2;

  1. 开始第三轮,i=2开始。

    a). v[2]=true; j=d[2]=4

    b). v[4]=true; j=d[4]=2

    c). v[2](v[2]已经为true,不会运行if,构成循环了,即d的4→2→4)

0123456789
vtruetruetruefalsetruefalsefalsetruetruefalse
d7143259806

每结束一次if,cnt+1,即cnt=3;

  1. 开始第四轮,i=3开始。

    a). v[3]=true; j=d[3]=3

    b). v[3](v[3]已经为true,不会运行if,构成循环了,即d的3→3)

0123456789
vtruetruetruetruetruefalsefalsetruetruefalse
d7143259806

每结束一次if,cnt+1,即cnt=4;

  1. 开始第五轮,i=4开始。

    a). (v[4]已经为true,不会运行if,退出)

0123456789
vtruetruetruetruetruetruefalsetruetruefalse
d7143259806

没有运行if,cnt=4;

  1. 开始第六轮,i=5开始。

    a).v[5]=true j=d[5]=5

    b)v[5] ( (v[5]已经为true,不会运行if,退出, d的5→5)

0123456789
vtruetruetruetruetruetruefalsetruetruefalse
d7143259806

每结束一次if,cnt+1,即cnt=5;

  1. 开始第七轮,i=6开始。

    a). v[6]=true j=d[6]=9

    b). v[9]=true j=d[9]=6

    c). v[9]( v[9]已经为true,不会运行if,退出, d的6→9→6)

每结束一次if,cnt+1,即cnt=6;

0123456789
vtruetruetruetruetruetruetruetruetruetrue
d7143259806

截止到这里,整个v数组都为false了,不会再运行if语句了,所以cnt不会再增加了。故最后结果是cnt=6;

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值