• 启智树提高组day1T1 3436 : A:Doughnut


    启智树提高组day1T1 3436 : A:Doughnut

    原题传送门

    题目描述

    Aloisia有很多很多甜甜圈。有一天,她在地上画了n+1个格子,想从第1个格子跳到第n+1个格子。规则是,Aloisia每到一个格子,都会放一个甜甜圈在里面。在第i个格子时,如果当前甜甜圈的数量是偶数,那么她会跳到第i+1个格子;否则她会跳到第Pi个格子(1≤Pi≤i)。若她到达了第n+1个格子,则立即结束。Aloisia想知道,她要跳多少次才能到达终点。答案对1000000007取模。

    输入

    输入的第一行包含一个正整数n,表示一共有n+1个格子;
    第二行包含n个正整数Pi ,含义如题目描述中所述。

    输出

    输出一个整数,表示Aloisia需要跳的次数,对1000000007取模。

    样例输入

    Copy  

    样例输入1
    2
    1 2
    
    样例输入2
    4
    1 1 2 3
    
    样例输入3
    5
    1 1 1 1 1
     

    样例输出

    Copy  

    样例输出1
    4
    
    样例输出2
    20
    
    样例输出3
    62

    提示

    对于20%的数据,有1 ≤ n ≤ 20;

    对于40%的数据,有1 ≤ n ≤ 2000;

    对于100%的数据,1 ≤ n ≤ 1000000。

    要求

    时间限制:2.0Sec    内存限制:256MB

    建立模型

    由样例可得,前进一格后,先放甜甜圈,再判断奇偶性。

    故有:对于脚下的格子,如果是奇数次到达则回到p[i],如果是偶数次到达则向后走。

    当然,知道这个,也许不能完全做出来。那么就要接下来的性质了。

    性质:当第一次走到i+1个格子的时候,前i个格子里面的甜甜圈数量都为偶数个。

    又因为,如果是奇数次(比如首次)到底必定回到p[i]后又会前进到i,故这个可以看作是一个递推。

    f[i]=f[p[i]~i-1]+2;

    f[i]表示第一次走到i格时,要走f[i]步才能走回到第i格

    +2意为有两次从i-1走到i

    最后,求f[p[i]~i]可以用前缀和(这是我的做法)

    亦或,f[i]=f[i-1]+2+(f[i-1]-f[p[i])(std)

    数据生成

     1 #include<iostream>
     2 #include<algorithm>
     3 #include<cstdio>
     4 #include<cstring>
     5 #include<cmath>
     6 #include<map>
     7 #include<set>
     8 #include<queue>
     9 #include<vector>
    10 #include<ctime>
    11 #define IL inline
    12 #define re register
    13 #define LL long long
    14 #define ULL unsigned long long
    15 using namespace std;
    16 //当到达post时,前面的tt全都是偶数(再走过去就会变成偶数) 
    17 int n;
    18 
    19 int main()
    20 {
    21     srand(clock());
    22     cin>>n;
    23     freopen("t1.out","w",stdout);
    24     cout<<n<<endl;
    25     for(int i=1;i<=n;i++) cout<<rand()%i+1<<" ";
    26     return 0;
    27 }
    数据生成

    注意p[i]应当小于等于i。

    code

    task1

     1 #include<iostream>
     2 #include<algorithm>
     3 #include<cstdio>
     4 #include<cstring>
     5 #include<cmath>
     6 #include<map>
     7 #include<set>
     8 #include<queue>
     9 #include<vector>
    10 #define IL inline
    11 #define re register
    12 #define LL long long
    13 #define ULL unsigned long long
    14 using namespace std;
    15 /*
    16 Aloisia每到一个格子,都会放一个甜甜圈在里面。在第i个格子时,
    17 
    18 如果当前甜甜圈的数量是偶数,那么她会跳到第i+1个格子;
    19 
    20 否则她会跳到第Pi个格子(1≤Pi≤i)。
    21 
    22 */
    23 
    24 IL int read()
    25 {
    26     int ans=0;
    27     bool fu=0;
    28     char ch=getchar();
    29     while((ch>'9'||ch<'0')&&ch!='-') ch=getchar();
    30     if(ch=='-') fu=1,ch=getchar();
    31     while(ch<='9'&&ch>='0') ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar();
    32     if(fu) ans*=-1;
    33     return ans;
    34 }
    35 
    36 const int M = 1000000007;
    37 
    38 int n,ans;
    39 
    40 int p[1000010];
    41 
    42 int tt[1000010];
    43 
    44 int main()
    45 {
    46     freopen("t1.out","r",stdin); 
    47     cin>>n;
    48     for(int i=1;i<=n;i++) p[i]=read();
    49     int post=1;
    50     while(post<=n)
    51     {
    52         ans++;
    53         if(ans>M) ans-=M;
    54         
    55         
    56 //        cout<<ans;
    57 //        cout<<"当前位置"<<post<<endl; 
    58 //        cout<<"当前tt"<<tt[post]<<endl;
    59         
    60         if(tt[post]&1) tt[post]++,post++;
    61         else tt[post]++,post=p[post];
    62 //        getchar();
    63         
    64     }
    65     cout<<ans;
    66     return 0;
    67 }
    暴力

    task2

    没打。

    task3

     1 #include<iostream>
     2 #include<algorithm>
     3 #include<cstdio>
     4 #include<cstring>
     5 #include<cmath>
     6 #include<map>
     7 #include<set>
     8 #include<queue>
     9 #include<vector>
    10 #define IL inline
    11 #define re register
    12 #define LL long long
    13 #define ULL unsigned long long
    14 using namespace std;
    15 /*
    16 Aloisia每到一个格子,都会放一个甜甜圈在里面。在第i个格子时,
    17 
    18 如果当前甜甜圈的数量是偶数,那么她会跳到第i+1个格子;
    19 
    20 否则她会跳到第Pi个格子(1≤Pi≤i)。
    21 
    22 */
    23 
    24 IL int read()
    25 {
    26     int ans=0;
    27     bool fu=0;
    28     char ch=getchar();
    29     while((ch>'9'||ch<'0')&&ch!='-') ch=getchar();
    30     if(ch=='-') fu=1,ch=getchar();
    31     while(ch<='9'&&ch>='0') ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar();
    32     if(fu) ans*=-1;
    33     return ans;
    34 }
    35 
    36 const int M = 1000000007;
    37 
    38 int n,ans;
    39 
    40 int p[1000010];
    41 
    42 bool tt[1000010];
    43 
    44 int jump[1000010];
    45 
    46 int qjump[1000010];
    47 
    48 int main()
    49 {
    50     freopen("t1.out","r",stdin); 
    51     cin>>n;
    52     for(int i=1;i<=n;i++){
    53         p[i]=read();
    54         jump[i]=2;
    55         if(i!=p[i]){
    56 //            for(int j=p[i];j<i;j++) jump[i]+=jump[j];
    57             jump[i]+=(qjump[i-1]+M-qjump[p[i]-1])%M;
    58         }
    59         qjump[i]=qjump[i-1]+jump[i];
    60         qjump[i]%=M;
    61 //        cout<<i<<" "<<jump[i]<<endl;
    62         ans+=jump[i]; 
    63         ans%=M;
    64     }
    65     
    66     cout<<ans;
    67     return 0;
    68 }

    std

     1 #include <bits/stdc++.h>
     2 
     3 using namespace std;
     4 
     5 typedef long long ll;
     6 
     7 const int N = 1e6 + 10;
     8 
     9 const int P = 1e9 + 7;
    10 
    11 int n, p[N];
    12 
    13 ll f[N];
    14 
    15 
    16 
    17 int main(){
    18 
    19     freopen("Doughnut.in", "r", stdin);
    20 
    21     freopen("Doughnut.out", "w", stdout);
    22 
    23     scanf("%d", &n);
    24 
    25     for(int i = 1;i <= n; i++)
    26 
    27         scanf("%d", &p[i]);
    28 
    29     f[1] = 0;
    30 
    31     for(int i = 1;i <= n; i++)
    32 
    33         f[i + 1] = (f[i] + 1 + f[i] - f[p[i]] + 1) % P;
    34 
    35     printf("%lld
    ",(f[n + 1] + P) % P);
    36 
    37     return 0;
    38 
    39 }

    小结

    考试中得分100。

    两天以来唯一一道AC题……(哭/(ㄒoㄒ)/~~

    这种小题目要快速思考,给后面的题目留时间。

  • 相关阅读:
    android.database.CursorIndexOutOfBoundsException: Index -1 requested, with a size of 3
    display:inline-block的运用
    图解单片机8位PWM、16位PWM中“位”的含义!
    UVA10006
    [置顶] CF 86D Powerful array 分块算法入门,n*sqrt(n)
    俗人解释 三维渲染 在工作过程
    HDU 4414 Finding crosses(dfs)
    Codeforces 35E Parade 扫描线 + list
    hdu 4374 单调队列
    LeetCode OJ平台Sort Colors讨论主题算法
  • 原文地址:https://www.cnblogs.com/send-off-a-friend/p/13524813.html
Copyright © 2020-2023  润新知