zoukankan      html  css  js  c++  java
  • Hdu

      因为考试所以最近都没有做什么题。想不到这题都卡(~~~~(>_<)~~~~ ),看来太久没有做题感觉变迟钝了,当然也有原因是找规律的题做得比较少,所以就这样了,看来要快快调整好,好好努力才行。

    先上题目

    Eddy's 洗牌问题

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
    Total Submission(s): 2602    Accepted Submission(s): 1718


    Problem Description
    Eddy 是个ACMer,他不仅喜欢做ACM题,而且对于纸牌也有一定的研究,他在无聊时研究发现,如果他有2N张牌,编号为 1,2,3..n,n+1,..2n。这也是最初的牌的顺序。通过一次洗牌可以把牌的序列变为 n+1,1,n+2,2,n+3,3,n+4,4..2n,n。那么可以证明,对于任意自然数N,都可以在经过M次洗牌后第一次重新得到初始的顺序。编程 对于小于100000的自然数N,求出M的值。
     

     

    Input
    每行一个整数N
     

     

    Output
    输出与之对应的M
     

     

    Sample Input
    20 1
     

     

    Sample Output
    20 2
     
     
     
      数据范围一看就知道不可以直接模拟,于是先先写了一个直接模拟的看看规律,结果没有看出什么端倪出来。只发现1的位置一开始是1->2->4···这样变化,后来还是不得不上网看了一下题解,发现只需要判断1有没有回到一开始的位置就可以了,1的变化就是一开始是1->2->4```这样变化,但是当去到后面到达不了2的n次幂的情况下,就要按照题目的方法把1放回到前面,位置在(i-n)*2-1,其中i是1的当前位置,n是输入的n,i要大于n且i*2也要大于2*n才执行这一步。
     
    上代码
     1 #include <stdio.h>
     2 #include <stdlib.h>
     3 #include <string.h>
     4 #define MAX 10000
     5 
     6 using namespace std;
     7 /*
     8 typedef struct
     9 {
    10     int d[MAX];
    11 }D;
    12 
    13 D s;
    14 
    15 void loadlist(D u,int m)
    16 {
    17     int i;
    18     for(i=1;i<=m;i++) printf("%d ",u.d[i]);
    19     printf("
    ");
    20 }
    21 
    22 bool check(D u,int m)
    23 {
    24     int i;
    25     for(i=1;i<=m;i++) if(u.d[i]!=s.d[i]) return 0;
    26     return 1;
    27 }
    28 
    29 void deal(int n)
    30 {
    31     int i,j,m,count;
    32     D u,v;
    33     m=n*2;
    34     count=0;
    35     u=s;
    36     loadlist(u,m);
    37     while(!count || !check(u,m))
    38     {
    39         for(j=2,i=1;j<=m;j+=2,i++) v.d[j]=u.d[i];
    40         for(j=1;j<=m;j+=2,i++) v.d[j]=u.d[i];
    41         u=v;
    42         count++;
    43         loadlist(u,m);
    44     }
    45     printf("%4d %4d %4d
    ",n,m,count);
    46 }
    47 
    48 int main()
    49 {
    50     int n,i;
    51     char o;
    52     n=0;
    53     freopen("data.txt","w",stdout);
    54     while(n<=100)
    55     {
    56         //(o=getchar())!=EOF
    57         n++;
    58         for(i=1;i<=2*n;i++) s.d[i]=i;
    59         deal(n);
    60     }
    61     return 0;
    62 }
    63 */
    64 
    65 int main()
    66 {
    67     int i,n,m,count;
    68     while(scanf("%d",&n)!=EOF)
    69     {
    70         i=1;
    71         m=2*n;
    72         count=0;
    73         while(!count || i!=1)
    74         {
    75             if(i*2>m && i>n)
    76             {
    77                 i-=n;
    78                 i=i*2-1;
    79             }
    80             else i*=2;
    81             count++;
    82         }
    83         printf("%d
    ",count);
    84     }
    85     return 0;
    86 }

      其中前面的代码用来直接模拟得到每一步的序列,同时有最后的移动步数。真正需要提交的代码只有一小段。

        
  • 相关阅读:
    Sharding-JDBC(三)3.1.0版本实践
    Sharding-JDBC(二)2.0.3版本实践
    Sharding-JDBC(一)简介
    Java并发(六)线程池监控
    Java并发(五)线程池使用番外-分析RejectedExecutionException异常
    Java并发(四)线程池使用
    Java并发(三)线程池原理
    Java并发(二)异步转同步
    tarjan+概率
    线段树(种树)
  • 原文地址:https://www.cnblogs.com/sineatos/p/3169631.html
Copyright © 2011-2022 走看看