zoukankan      html  css  js  c++  java
  • ZOJ Problem Set–1489 2^x mod n = 1

    Time Limit: 2 Seconds      Memory Limit: 65536 KB


    Give a number n, find the minimum x that satisfies 2^x mod n = 1.

    Input

    One positive integer on each line, the value of n.

    Output

    If the minimum x exists, print a line with 2^x mod n = 1.

    Print 2^? mod n = 1 otherwise.

    You should replace x and n with specific numbers.

    Sample Input

    2
    5

    Sample Output

    2^? mod 2 = 1
    2^4 mod 5 = 1



    Author: MA, Xiao
    Source: ZOJ Monthly, February 2003

    这道题看起来描述是够少的,我就喜欢这种题目,本人英文不是很好。。。。

    题目非常清晰,就是要求2的X次方除以N的余数为1时的X的值。刚看到这道题目的时候,我不假思索的就认为,这种题目通过表驱动的方式是一个很好的办法,于是我就想着先打一张2的32次方的表格,然后每次求结果的时候只要遍历这张表就可以了,于是就有了下述代码:

    #include<iostream>
    
    using namespace std;
    
    const int NUM = 32;
    
    int *pow2 = new int[NUM]; 
    
    void initial2Pow()
    
    {
    
      *pow2 = 1;
    
      for(int i = 1; i < NUM; i++)
    
        *(pow2 + i) = 2*(*(pow2 + i - 1));
    
    }
    
    int main()
    
    {
    
      initial2Pow();
    
      int n;
    
      while(cin>>n)
    
      {
    
        if(n%2 == 0 || n < 2)
    
        {
    
          cout<<"2^? mod "<<n<<" = 1"<<endl;
    
          continue;
    
        }
    
        bool find = false;
    
        for(int i = 1;i < NUM;i++)
    
        {
    
          if((*(pow2 + i))%n == 1)
    
          {
    
            cout<<"2^"<<i<<" mod "<<n<<" = 1"<<endl;
    
            find = true;
    
            break;
    
          }
    
        }
    
        if(!find)
    
        {
    
          cout<<"2^? mod "<<n<<" = 1"<<endl;
    
        }
    
      }
    
    }

    感觉代码比较简练,可以提交了,但是已提交却得到了WA!这时,我意识到可能是由于精度问题,int 的32位可能不够,于是我用64 位 long long 来代替int,重新提交之后,仍然得到WA !这时我发现,这题其实还是不是那么简单的!至少不应该仅仅是简单的表驱动来解决这个问题。还是需要一些数学技巧的。首先我把计算过程用笔写在了之上:

    a / b = c …………..d,此时等式两边乘以2,得到2a / b = 2c ……. 2d, 此时发现,2a % b得到的余数,与2d%b的余数是一样的!

    若2d / b = c0…..d0, 则有2a / b = 2c + c0 …….d0, 有了这些数学的推论后,修正代码如下:

    #include<iostream>
    
    using namespace std;
    
    int main()
    
    {
    
      int n;
    
      while(cin>>n)
    
      {
    
        if(n%2 == 0 || n < 2)
    
        {
    
          cout<<"2^? mod "<<n<<" = 1"<<endl;
    
          continue;
    
        }
    
        bool find = false;
    
        int d = 1;
    
        for(int i = 1;;i++)
    
        {
    
          d *= 2;
    
          if(d%n == 1)
    
          {
    
            cout<<"2^"<<i<<" mod "<<n<<" = 1"<<endl;
    
            find = true;
    
            break;
    
          }
    
          d = d%n;
    
        }
    
        if(!find)
    
        {
    
          cout<<"2^? mod "<<n<<" = 1"<<endl;
    
        }
    
      }
    
    }
    成功AC !
  • 相关阅读:
    vector.clear()无法释放内存的对策
    www.wangtam.com
    VC 控件的字体控制 若将字体设置成“宋体、仿宋—GB2312、隶书、幼圆”中的某一字体时,需将lfCharSet设置成GB2312—CHARSET才使设置的字体有效
    CPU使用率 武胜
    MySQL数据类型 转 武胜
    按小时统计的语句 转 武胜
    MYSQL 行转成列 转 武胜
    推荐一个 开源C#股票软件 武胜
    WCF传输泛型 List 对象 转 武胜
    WCF 传输大数据的问题 转 武胜
  • 原文地址:https://www.cnblogs.com/malloc/p/2425600.html
Copyright © 2011-2022 走看看