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, 有了这些数学的推论后,修正代码如下:
成功AC !#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;}}}