Timus 1110. Power 要求计算乘方(取模)问题。
1110. Power
Time Limit: 0.5 second
Memory Limit: 16 MB
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
input | output |
---|---|
2 6 4 |
2 4 |
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
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
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;
}
{
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 秒。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· [AI/GPT/综述] AI Agent的设计模式综述