笔试题

chlaws 2008-03-04 07:04:45
从键盘输入m,n.计算m^n;
m>1,0<n<100;
输出m^n的百位,十位,个位的值.
>要考虑数据溢出.
...全文
396 27 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
27 条回复
切换为时间正序
请发表友善的回复…
发表回复
wjwwgh 2008-03-06
  • 打赏
  • 举报
回复
要考虑溢出的.
p0303230 2008-03-06
  • 打赏
  • 举报
回复
[Quote=引用 18 楼 mathe 的回复:]
更加有效的方法是对n各个二进制位进行分析,这样就可以非常有效的处理很大的n的情况(比如n远远大于100的情况)

C/C++ code
int f(int m,int n){
int mul=m%n;
int r=1;
while(n){
if(n&1){r*=mul;r%=1000;}
mul*=mul;mul%=1000;
n>>=1;
}
return r;
}
[/Quote]
mathe 老大能解释一下吗 这是求个位数吗?
mathe 2008-03-06
  • 打赏
  • 举报
回复
对于非常大的n,还有公式:
m^(100u+v) (mod 1000)= m^v (mod 1000) (v>=3时)
通常可以事先用n%100代替n,唯一例外是当n%100<3而且(m,1000)!=1时
visame 2008-03-06
  • 打赏
  • 举报
回复

我总结一下楼上各位的答案:
1.利用A*B mod M=((A mod M)*(B Mod M))Mod M;
2.利用Modular_Exponentation,把指数化为二进制计算。
两种算化都不会溢出。
sw1024 2008-03-05
  • 打赏
  • 举报
回复
不用管溢出,考虑最后三位即可
bizhan 2008-03-05
  • 打赏
  • 举报
回复
mark
小鬼_CHEN 2008-03-05
  • 打赏
  • 举报
回复
mark
IlikeEnglish 2008-03-05
  • 打赏
  • 举报
回复
直接乘法,不用考虑溢出。即使溢出也可以保证最后三位的有效性
mathe 2008-03-05
  • 打赏
  • 举报
回复
更加有效的方法是对n各个二进制位进行分析,这样就可以非常有效的处理很大的n的情况(比如n远远大于100的情况)

int f(int m,int n){
int mul=m%n;
int r=1;
while(n){
if(n&1){r*=mul;r%=1000;}
mul*=mul;mul%=1000;
n>>=1;
}
return r;
}

visame 2008-03-05
  • 打赏
  • 举报
回复
1000取余是正解。
baihacker 2008-03-04
  • 打赏
  • 举报
回复
to 14 楼
换为unsigned int long
假设m = 0xffffffff
你试试...
dubiousway 2008-03-04
  • 打赏
  • 举报
回复
~~ 刚刚看到 11楼已经写出来了 。。
dubiousway 2008-03-04
  • 打赏
  • 举报
回复

unsigned result=1;

for(int i=0;i <n;i++){
result= (result%1000)*m;
printf("%8d\n", result);
}


这样就没问题了。比如
n=20,m=7

int n= 20;
unsigned int m=7;
unsigned result=1;

for(int i=0;i <n;i++){
result= (result%1000)*m;
printf("%8d\n", result);
}


结果:

7
49
343
2401
2807
5649
4543
3801
5607
4249
1743
5201
1407
2849
5943
6601
4207
1449
3143
1001
canybox 2008-03-04
  • 打赏
  • 举报
回复
8楼的正解!
拆分为科学计算,再计算.
独孤过儿 2008-03-04
  • 打赏
  • 举报
回复
考虑溢出,那就得先做个大数类出来了,然后再计算...
baihacker 2008-03-04
  • 打赏
  • 举报
回复
1楼的程序应该改成
int result = 1;
int t = m % 1000;
for (int i = 0; i < n; ++i)
result = (result * t) % 1000;
以前那个会溢出的...
xhd3767 2008-03-04
  • 打赏
  • 举报
回复
用Char[]存储 判断!!可以的
abupie 2008-03-04
  • 打赏
  • 举报
回复
不好意思,最后应该是

int res = 0;
for (int i = 0; i < n; i++)
{
res = f(m, res);
}

手误
abupie 2008-03-04
  • 打赏
  • 举报
回复
把数字m1表示为: m1 = a[t] * 10^t + a[t-1] * 10^(t-1) + ... + a[2] * 10^2 + a[1] * 10 + a[0];
其中a[0] - a[t]表示个位到最高位。
把数字m2 = b[k] * 10^k + b[k-1] * 10^(k-1) + ... + b[2] * 10^2 + b[1] * 10 + b[0];

m1 * m2就是
(a[t] * 10^t + a[t-1] * 10^(t-1) + ... + a[2] * 10^2 + a[1] * 10 + a[0]) *
(b[k] * 10^k + b[k-1] * 10^(k-1) + ... + b[2] * 10^2 + b[1] * 10 + b[0])。
如果t,k都是大于2的,乘积中对于a[3] - a[t], b[3] - b[k]相乘的部分肯定是超过1000的,这些可以忽略。也就是说m1 * m2的个位 - 百位其实和
(100*a[2] + 10*a[1] + a[0]) * (100*b[2] + 10*b[1] + b[0])
是一样的。

(100*a[2] + 10*a[1] + a[0]) * (100*b[2] + 10*b[1] + b[0])
= 10000*a[2]*b[2] + 1000*a[2]*b[1] + 100*a[2]*b[0]+
1000*a[1]*b[2] + 100*a[1]*b[1] + 10*a[1]*b[0]+
100*a[0]*b[2] + 10*a[0]*b[1] + a[0]*b[0]
再去掉肯定超过1000的, 得到简化后的结果:100*a[2]*b[0] + 100*a[1]*b[1] + 10*a[1]*b[0] + 100*a[0]*b[2]+10*a[0]*b[1]+a[0]*b[0];

按这个思路,代码如下:
int f(m1, m2)
{
int a2 = m1/100%10;
int a1 = m1/10%10;
int a0 = m1%10;

int b2 = m2/100%10;
int b1 = m2/10%10;
int b0 = m2%10;

int res = 100*a2*b0 + 100*a1*b1 + 10*a1*b0 + 100*a0*b2 + 10*a0*b1 + a0*b0;
res = res % 1000;
return res;
}

int res = 0;
for (int i = 0; i < n; i++)
{
res = f(n, res);
}
baihacker 2008-03-04
  • 打赏
  • 举报
回复
再补充一下
假设是使用的double
十进制可以达到小数点到16位的精度
那么存在某个数m,其n次方,和小数点第16位的数有关

也就是说计算过程中,一定要保证小数点后第16位的数字的有效性

浮点数一乘方,你能保证乘出来的数在个十百位上是有效的吗?
加载更多回复(7)

70,031

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧