トップページに戻る
次の競技プログラミングの問題へ
前の競技プログラミングの問題へ
No.167 N^M mod 10
■■■問題■■■
(NのM乗)mod10を求めよ。
■■■入力■■■
N
M
1行目にN, 2行目にMが与えられる。
1 <= N <= 10の10000乗
0 <= M <= 10の10000乗
■■■出力■■■
(NのM乗)mod10を出力せよ。
C#のソース
using System;
using System.Collections.Generic;
class Program
{
static string InputPattern = "Input1";
static List<string> GetInputList()
{
var WillReturn = new List<string>();
if (InputPattern == "Input1") {
WillReturn.Add("22");
WillReturn.Add("22");
//4
}
else if (InputPattern == "Input2") {
WillReturn.Add("56");
WillReturn.Add("65");
//6
}
else {
string wkStr;
while ((wkStr = Console.ReadLine()) != null) WillReturn.Add(wkStr);
}
return WillReturn;
}
static void Main()
{
List<string> InputList = GetInputList();
string StrN = InputList[0];
int IntN = int.Parse(StrN.Substring(StrN.Length - 1));
string StrM = InputList[1];
//0乗は1
if (StrM == "0") {
Console.WriteLine(1);
return;
}
//Nの1桁目に対応する循環数列
string JyunkanStr = DeriveJyunkanStr(IntN);
int Hou = JyunkanStr.Length;
//Mを法で割った余り
int ModVal = DeriveMod(StrM, Hou);
Console.WriteLine("{0}を{1}で割った余りは{2}", StrM, Hou, ModVal);
int TargetInd = ModVal - 1;
if (TargetInd == -1) TargetInd = Hou - 1;
Console.WriteLine(JyunkanStr[TargetInd]);
}
//Mを法で割った余りを返す
static int DeriveMod(string pStrM, int pHou)
{
//法が1の場合
if (pHou == 1) return 0;
int WillReturn = 0;
int Jyousuu = 1;
for (int I = pStrM.Length - 1; 0 <= I; I--) {
int CurrNum = pStrM[I] - '0';
WillReturn = (WillReturn + CurrNum * Jyousuu) % pHou;
Jyousuu = (Jyousuu * 10) % pHou;
}
return WillReturn;
}
//Nの1桁目に対応する循環数列を返す
static string DeriveJyunkanStr(int pIntN)
{
if (pIntN == 0) return "0";
if (pIntN == 1) return "1";
if (pIntN == 2) return "2486";
if (pIntN == 3) return "3971";
if (pIntN == 4) return "46";
if (pIntN == 5) return "5";
if (pIntN == 6) return "6";
if (pIntN == 7) return "7931";
if (pIntN == 8) return "8426";
return "91";
}
}
解説
オ−バーフロー対策で、Nは1の位のみを使用してます。
Nの1の位が決まれば、自乗を繰り返した時の、1の位の循環数列も決まります。
そして、Mを読み込み際に、
循環数列の長さを法とした時の、余りのみを取得するようにしてます。