Timus 1110. Power 要求计算乘方(取模)问题。
1110. Power
Time Limit: 0.5 second
Memory Limit: 16 MB
You are given the whole numbers
N,
M and
Y. Write a program that will find all whole numbers
X in the interval [0,
M−1] such that
XN mod
M =
Y.
Input
The input contains a single line with
N,
M and
Y (0 <
N < 999, 1 <
M < 999, 0 <
Y < 99) separated with one space.
Output
Output all numbers
X separated with space on one line. The numbers must be written in ascending order. If no such numbers exist then output −1.
Sample
Problem Source: Bulgarian National Olympiad Day #1
解答如下:
1
using
System;
2
3
namespace
Skyiv.Ben.Timus
4
{
5
//
http://acm.timus.ru/problem.aspx?space=1
&num=1110
6
sealed
class
T1110
7
{
8
static
void
Main()
9
{
10
string
[] ss
=
Console.ReadLine().Split();
11
int
n
=
int
.Parse(ss[
0
]);
12
int
m
=
int
.Parse(ss[
1
]);
13
int
y
=
int
.Parse(ss[
2
]);
14
bool
ok
=
false
;
15
for
(
int
x
=
0
; x
<
m; x
++
)
16
{
17
if
(ModPow(x, n, m)
==
y)
18
{
19
ok
=
true
;
20
Console.Write(x
+
"
"
);
21
}
22
}
23
if
(
!
ok) Console.Write(
-
1
);
24
}
25
26
static
int
ModPow(
int
x,
int
n,
int
m)
27
{
28
int
z
=
1
;
29
for
(
int
i
=
0
; i
<
n; i
++
) z
=
(z
*
x)
%
m;
30
return
z;
31
}
32
}
33
}
34
这里关键是 ModPow 方法。如果是 Pow 方法,以下实现比较高效:
1
static
int
Pow(
int
x,
int
n)
2
{
3
int
z
=
1
;
4
for
(
int
p
=
x; n
>
0
; n
>>=
1
, p
*=
p)
if
((n
&
1
)
!=
0
) z
*=
p;
5
return
z;
6
}
7
不过,Pow 方法很容易溢出,更适用于 x 和 z 是 BigInteger 的情形。
根据3楼 guest 朋友的评论,可以将程序中第 26 到 31 行的 ModPow 方法改为以下更高效的代码:
static
int
ModPow(
int
x,
int
n,
int
m)
{
int
z
=
1
;
for
(
int
p
=
x; n
>
0
; n
>>=
1
, p
=
(p
*
p)
%
m)
if
((n
&
1
)
!=
0
) z
=
(z
*
p)
%
m;
return
z;
}
经测试,运行时间从原来的 0.14 秒降低到 0.125 秒。
返回目录