If N Ns are added together, we know that it's the square of N. Well, if N Ns are multiplied together, we call it a super square of N. For example, the square of 3 is 3+3+3=9, while the super square is 3*3*3=27. It is quite easy for you, a clever programming fan, to calculate the super square of integers. Am I right?
Input
The input consists of several lines, each line contains an integer N (0 < N < 108). Input is terminated by N=0.
Output
For each test case, print a line with a single integer, which is the remainder of N's super square divides 2006 (the N's super square MOD 2006).
Sample Input
2 3 4 0
Sample Input
4 27 256
题意概述:本题要求输出 N 的 N 次幂 模 2006 的结果。如上例中,当输入为3时,要求输出 3*3*3 % 2006 。
解题思路:本题主要用到数论中的同余知识,即 若 A%m=B%m ,则 A的n次幂%m = B的n次幂%m 。如此,即可将大于2006的数的 运算转化为比2006小的数的运算。但是要注意,即使小于2006,但当N很大时,要求N次乘法运算,这样的话程序会超 时。分析题意可知,任何一个数 %2006必是一个在0-2005之间的数,即在2007次运算后必然会出现重复的数字,即出现 了循环节,如此便将循环的次数控制在2006次左右。
源代码:
#include<iostream>
#include<algorithm>
#include<deque>
using namespace std;
int main()
{
int N;
deque<int>Set; //该集合用来存放已经出现过的余数
deque<int>::iterator pos; //迭代器,搜寻
while(cin>>N&&N)
{
int result,factor,len,time;
if(N%2006==0)result=0; //特殊情况
else
{
result=N%2006;
factor=result;
Set.push_back(result); //一次幂时的余数
for(int i=2;i<=N;++i)
{
result=result*factor%2006;
pos=find(Set.begin(),Set.end(),result); //查找result是否已经存在
if(pos!=Set.end()){ //存在
len=distance(pos,Set.end());//计算循环节的长度
time=(N-i+1)%len; //求模
if(time==0)pos=Set.end()-1; //若正好是循环节长度的n倍,则是循环节的最后一个元素
else advance(pos,time-1); //否则 将pos向后移动time-1个
result=*pos;
break; //终止循环
}
else Set.push_back(result); //若不存在,则将此次计算结果插入Set后
}
Set.clear(); //清空Seg,避免影响下一次输入
}
cout<<result<<endl;
}
return 0;
}
//当N>2006时一定会有循环节出现
#include<algorithm>
#include<deque>
using namespace std;
int main()
{
int N;
deque<int>Set; //该集合用来存放已经出现过的余数
deque<int>::iterator pos; //迭代器,搜寻
while(cin>>N&&N)
{
int result,factor,len,time;
if(N%2006==0)result=0; //特殊情况
else
{
result=N%2006;
factor=result;
Set.push_back(result); //一次幂时的余数
for(int i=2;i<=N;++i)
{
result=result*factor%2006;
pos=find(Set.begin(),Set.end(),result); //查找result是否已经存在
if(pos!=Set.end()){ //存在
len=distance(pos,Set.end());//计算循环节的长度
time=(N-i+1)%len; //求模
if(time==0)pos=Set.end()-1; //若正好是循环节长度的n倍,则是循环节的最后一个元素
else advance(pos,time-1); //否则 将pos向后移动time-1个
result=*pos;
break; //终止循环
}
else Set.push_back(result); //若不存在,则将此次计算结果插入Set后
}
Set.clear(); //清空Seg,避免影响下一次输入
}
cout<<result<<endl;
}
return 0;
}
//当N>2006时一定会有循环节出现