• 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 !
  • 相关阅读:
    基于HTTP和TFTP的PXE批量自动化安装Linux系统
    使用U盘进行Linux系统的安装
    CentOS 7单用户模式修改root密码
    LVS的调度算法分析
    linux LVS DR模式配置
    Nagios的客户端的安装
    Nagios监控系统的安装
    Linux内核升级
    redhat linux使用Centos yum源
    Juniper srx防火墙NAT配置
  • 原文地址:https://www.cnblogs.com/malloc/p/2425600.html
Copyright © 2020-2023  润新知