トップページに戻る
次の競技プログラミングの問題へ
前の競技プログラミングの問題へ
No.176 2種類の切手
■■■問題■■■
Yuki王国では、A円とB円の2種類の郵便切手が発行されています。
あなたは、これら2種類の切手をうまく組み合わせて、
郵便物にT円分以上の切手を貼ろうとしていますが、
切手の合計額がなるべく少なくなるようにしなければなりません。
切手の合計額が最も少なくなるようにしたとき、
何円分の切手を貼ることになるでしょうか?
その合計額を答えてください。
なお、必ずしも両方の種類の切手を使う必要はなく、
切手の枚数に制限はありません。
■■■入力■■■
A B T
1 <= A<B <= 10億
1 <= T <= 10億
A, B, T はいずれも整数です。
■■■出力■■■
切手の合計額を出力してください。
C#のソース
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static string InputPattern = "Input4";
static List<string> GetInputList()
{
var WillReturn = new List<string>();
if (InputPattern == "Input1") {
WillReturn.Add("50 80 120");
//130
//50円切手と80円切手を組み合わせて、ちょうど120円にすることはできません。
//この場合、50円切手と80円切手を1枚ずつ使って130円にするのが、
//120円以上での最少額になります。
}
else if (InputPattern == "Input2") {
WillReturn.Add("123 456 1");
//123
//必ずしも両方の種類の切手を使う必要はありません。
//この場合、額面の小さい123円の切手を1枚貼ることになります。
}
else if (InputPattern == "Input3") {
WillReturn.Add("1234 1688 10000");
//10000
//うまくすれば、ちょうど10000円にできるようです。
}
else {
string wkStr;
while ((wkStr = Console.ReadLine()) != null) WillReturn.Add(wkStr);
}
return WillReturn;
}
static void Main()
{
List<string> InputList = GetInputList();
int[] wkArr = InputList[0].Split(' ').Select(X => int.Parse(X)).ToArray();
int A = wkArr[0];
int B = wkArr[1];
int T = wkArr[2];
//AかBの倍数なら、解が確定
if (T % A == 0 || T % B == 0) {
Console.WriteLine(T);
return;
}
int MinSumVal = int.MaxValue;
int SumVal;
//場合1 Aの切手だけを使う場合
SumVal = T + (A - T % A);
if (MinSumVal > SumVal) MinSumVal = SumVal;
//場合2 Bの切手だけを使う場合
SumVal = T + (B - T % B);
if (MinSumVal > SumVal) MinSumVal = SumVal;
//場合3 両方の切手を使う場合
//Yを固定してXを求める
var ModASet = new HashSet<int>();
for (int Y = 0; B * Y < T; Y++) {
SumVal = B * Y;
int RestVal = T - SumVal;
int ModA = RestVal % A;
if (ModA == 0) {
Console.WriteLine(T);
return;
}
//同じModが出たらBreak
if (ModASet.Add(ModA) == false) break;
SumVal = T + (A - ModA);
if (MinSumVal > SumVal) MinSumVal = SumVal;
}
Console.WriteLine(MinSumVal);
}
}
解説
まず、TがAかBの倍数なら、解はTで確定します。
そうでない場合は、下記の3つの場合に分けます。
場合1 Aの切手だけを使う場合
場合2 Bの切手だけを使う場合
場合3 AとBの両方の切手を使う場合
場合3では、例えば、(A,B,T) = (3,5,1234)の場合は、
下記の不等式を考えることになります。
3X+5Y >= 1234
Y=0なら 3X >= 1234
Y=1なら 3X >= 1234-5
Y=2なら 3X >= 1234-5*2
Y=3なら 3X >= 1234-5*3
以下続くとなりますが、
1234 %3 = 1
(1234- 5)%3 = 2
(1234-10)%3 = 0
(1234-15)%3 = 1
といった感じで余りが循環しますので、
同じ余りが登場したらループをBreakさせてます。