AtCoderのPAST
次のPASTの問題へ
前のPASTの問題へ
第23回PAST E 分数のソート
C#のソース
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static string InputPattern = "InputX";
static List<string> GetInputList()
{
var WillReturn = new List<string>();
if (InputPattern == "Input1") {
WillReturn.Add("3");
WillReturn.Add("2 3");
WillReturn.Add("1 2");
WillReturn.Add("3 5");
//1 2
//3 5
//2 3
}
else if (InputPattern == "Input2") {
WillReturn.Add("5");
WillReturn.Add("1 5");
WillReturn.Add("1 7");
WillReturn.Add("6 5");
WillReturn.Add("9 8");
WillReturn.Add("9 4");
//1 7
//1 5
//9 8
//6 5
//9 4
}
else if (InputPattern == "Input3") {
WillReturn.Add("10");
WillReturn.Add("39 83");
WillReturn.Add("93 70");
WillReturn.Add("5 92");
WillReturn.Add("81 67");
WillReturn.Add("30 53");
WillReturn.Add("57 5");
WillReturn.Add("91 58");
WillReturn.Add("21 85");
WillReturn.Add("81 34");
WillReturn.Add("37 38");
//5 92
//21 85
//39 83
//30 53
//37 38
//81 67
//93 70
//91 58
//81 34
//57 5
}
else {
string wkStr;
while ((wkStr = Console.ReadLine()) != null) WillReturn.Add(wkStr);
}
return WillReturn;
}
static long[] GetSplitArr(string pStr)
{
return (pStr == "" ? new string[0] : pStr.Split(' ')).Select(pX => long.Parse(pX)).ToArray();
}
struct SortableStruct : IComparable<SortableStruct>
{
internal long A;
internal long B;
public int CompareTo(SortableStruct pOtherIns)
{
long[] Sahen1 = GetNumArr(A);
long[] Sahen2 = GetNumArr(pOtherIns.B);
long[] Uhen1 = GetNumArr(pOtherIns.A);
long[] Uhen2 = GetNumArr(B);
long[] SahenResult = GetProd(Sahen1, Sahen2);
long[] UhenResult = GetProd(Uhen1, Uhen2);
for (long I = 0; I <= SahenResult.GetUpperBound(0); I++) {
if (SahenResult[I] != UhenResult[I]) {
int Result = SahenResult[I].CompareTo(UhenResult[I]);
return Result;
}
}
return 0;
}
// 配列に値を設定して返す
private static long[] GetNumArr(long pVal)
{
long[] NumArr = new long[50];
long CurrInd = NumArr.GetUpperBound(0);
while (pVal > 0) {
NumArr[CurrInd] += pVal % 10;
pVal /= 10;
CurrInd--;
}
return NumArr;
}
// 配列2つの掛け算の結果を返す
private static long[] GetProd(long[] pNumArr1, long[] pNumArr2)
{
long[] ResultArr = new long[50];
for (long I = pNumArr1.GetUpperBound(0); 0 <= I; I--) {
if (pNumArr1[I] == 0) continue;
for (long J = pNumArr2.GetUpperBound(0); 0 <= J; J--) {
if (pNumArr2[J] == 0) continue;
long Diff = pNumArr2.GetUpperBound(0) - J;
long TargetInd = I - Diff;
ResultArr[TargetInd] += pNumArr1[I] * pNumArr2[J];
if (ResultArr[TargetInd] > 9) {
ResultArr[TargetInd - 1] += ResultArr[TargetInd] / 10;
ResultArr[TargetInd] %= 10;
}
}
}
for (long I = ResultArr.GetUpperBound(0); 0 <= I; I--) {
if (ResultArr[I] > 9) {
ResultArr[I - 1] += ResultArr[I] / 10;
ResultArr[I] %= 10;
}
}
return ResultArr;
}
}
static List<SortableStruct> mSortableStructList = new List<SortableStruct>();
static void Main()
{
List<string> InputList = GetInputList();
long[] wkArr = { };
Action<string> SplitAct = (pStr) => wkArr = GetSplitArr(pStr);
foreach (string EachStr in InputList.Skip(1)) {
SplitAct(EachStr);
SortableStruct WillAdd;
WillAdd.A = wkArr[0];
WillAdd.B = wkArr[1];
mSortableStructList.Add(WillAdd);
}
mSortableStructList.Sort();
mSortableStructList.ForEach(pX => Console.WriteLine("{0} {1}", pX.A, pX.B));
}
}
解説
10の18乗 * 10の18乗 はdecimal型でもオーバーフローするので
long型の配列を使用してます。