题解 P2227 【[HNOI2001]洗牌机】

· · 题解

纯枚举.(qwq)

由于逆推过程复杂,蒟蒻实在想不出qaq……思路如下:

#include<iostream>
#include<cstdio>
using namespace std;
int n,s,a[1005],b[1005],c[1005],cnt,z;
int main(){
    scanf("%d%d",&n,&s);
    for(int i=1;i<=n;i++){  //读入 
        scanf("%d",&a[i]);
        b[i]=a[i];  //令b数组与a相同,用于修改判断 
    }           
    for(z=1;z<=n;z++){      //正推(洗牌),推导出第几次时和a相同,得到的z即为周期数 
        for(int j=1;j<=n;j++){
            c[j]=b[b[j]];   //c数组为b正推(洗牌)出的下一个 
        }
        for(cnt=1;cnt<=n;cnt++){
            if(a[cnt]!=c[cnt]) break;   //一旦不同退出循环 
        }
        if(cnt==n+1) break;     //判断是否与a相同,相同则退出循环 
        for(int j=1;j<=n;j++){
            b[j]=c[j];  //让b数组更新为当前数组 
        }
    }
    s=z-s%z;    //重点!倒推次数即周期数-正推次数(%周期) 
    while(s--){     //洗牌 
        for(int j=1;j<=n;j++) b[j]=a[a[j]];
        for(int j=1;j<=n;j++) a[j]=b[j];
    }    
    for(int i=1;i<=n;i++) cout<<a[i]<<" ";  //输出 
}