zoukankan      html  css  js  c++  java
  • 传书本

    有 n 人, 每个人都正在读一本独一无二的小h书. 在每一天的结束的时候, 都会进行一次py交易,交易规则为:第 i 的人将给他的书给第 pi 的人 (如果i=pi,那么就是给他自己). 默认pi都是不同的数,是一个1到n的排列. 并且这个p是固定的,不随时间的改变而改变.

    例如, 如果 n=6 并且 p=[4, 6, 1, 3, 5, 2],那么第一天结束的时候进行了第一次py交易, 第1个人的书给了第4个人, 第2个人的书给了第6个人,依次类推.。第二天结束的时候,又进行了一次py交易,第1个人的书在第3个人的手里(因为第4个人给了第3个人), 第2个人的书又回到了自己这里(因为第6个人又给了第2个人),依次类推 .

    你的任务是确定在第几天后,第i个人的书回到了他自己本身。

    例如这个样例: p = [5, 1, 2, 4, 3]. 第一个人的书交易过程如下:
    第一天结束的时候第1个人给了第5个人
    第二天结束的时候第5个人给了第3个人
    第三天结束的时候第3个人给了第2个人
    第四天结束的时候第2个人给了第1个人

    所以4天后, 第一个人的书回到了他自己本身这里。 第四个人的书1天之后就回到了自己本身(因为当i=4的时候,i=pi)。

    你需要回答q个询问

    Input

    第一行输入一个q(1<=q<=1000),表示q个询问,对于每一个询问:
    第一行输入一个n(1<=n<=200000), 表示人的个数
    第二行输出n个整数,p1, p2, … , pn.

    Output

    对于每一个询问,输出n个整数 a1,a2,…,an, ai表示第i个人的书第一次回到了他本身所经历的天数

    Example

    Input
    6
    5
    1 2 3 4 5
    3
    2 3 1
    6
    4 6 2 1 5 3
    1
    1
    4
    3 4 1 2
    5
    5 1 2 4 3
    
    Output
    1 1 1 1 1 
    3 3 3 
    2 3 3 2 1 3 
    1 
    2 2 2 2 
    4 4 4 1 4 




    这个如果对于每一个人都进行dfs的话,一定会超时的
    所以要进行记忆化搜索
    那么如何进行记忆化搜索呢
    例如:
    5 1 2 4 3
    对于一的时候1->5->3->2->1
    其实他就构成一个环
    
    

    对于5的话:5->3->2->1->5

    对于这个环上的都是一样的步数

    #include<iostream>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    const int maxn=3e6+100;
    int a[maxn];
    int ans[maxn];
    int cnt=0;
    void dfs(int x,int pos){
        if(x!=a[pos]){
            cnt++;
            dfs(x,a[pos]);    
        }
        ans[pos]=cnt;
    }
    int main(){
        int t;
        cin>>t;
        while(t--){
            memset(ans,0,sizeof(ans));
            int n;
            cin>>n;
            for(int i=1;i<=n;i++){
                scanf("%d",&a[i]);
            }
            for(int i=1;i<=n;i++){
                if(!ans[i]){
                    cnt=1;
                    dfs(i,i); 
                } 
            } 
            for(int i=1;i<=n;i++){
                printf("%d ",ans[i]);
            }
            printf("
    "); 
        }
        
    }


  • 相关阅读:
    September 22nd 2016 Week 39th Thursday
    September 21st 2016 Week 39th Wednesday
    android 几个小技巧
    深入理解计算机系统----经验之谈
    输入数字如何获取
    super 和this的用法
    java程序员修炼之道
    eclipse 如何使用svn
    如何手动添加Android Dependencies包
    如何查看正在使用端口号并利用任务管理器将其关闭
  • 原文地址:https://www.cnblogs.com/lipu123/p/14146882.html
Copyright © 2011-2022 走看看