買えない金額
シャオミンはキャンディーストアを開きました。
フルーツキャンディを4個入りと7個入りの2パックに分けて包装するという工夫をしています。
キャンディーは包装されていない状態で販売することはできません。
子どもがお菓子を買いに来たとき、この2つのパッケージを組み合わせて使います。
もちろん、キャンディを10個買うなど、キャンディの数を結合することはできません。
パソコンで試すこともできますが、この場合購入できない数量は最大17個となります。
17 より大きい数値は、4 および 7 と組み合わせることができます。
この質問の要件は、2 つのパッケージの数量がわかっている場合に、組み合わせることができない最大の数を見つけることです。
入力フォーマット
各パッケージ内の砂糖の数を表す 2 つの正の整数 n、m。
出力フォーマット
購入できない砂糖の最大数を表す正の整数。
データ範囲
2≤n、m≤1000。データに解が存在することを保証します。
入力サンプル:
4 7
出力例:
17
前提条件: a と b が与えられた場合、d=gcd(a,b)>1 (つまり、最大公約数>1) の場合、最大の数を構成してはなりません。
d>1 の場合、a と b は d の倍数でなければならず、a と b で作られる数も d の倍数でなければならないため、最大数があってはならず、この数の後の数は次のようになります。 a と一緒に b
結論: a と b が両方とも正の整数で互いに素である場合、ax+by、x≥0、y≥0 から作れない最大の数は ( a−1)(b−1)−1 です (これは定理、証明するのは難しいので、定理を暗記するだけです)。
共素: 最大公約数は 1
Pei Shu の定理: a と b の最大公約数が d である場合、ap+bq=d となるような 2 つの整数 p と q はどのようにして存在することができますか。ab が互いに素である限り、解は存在するはずです。
ab が互いに素の場合、ap+bq=1 でなければならず、両辺に m を掛けます => apm+bqm=m => (am-q)p+(bm+p)q=m
方法 1. 暴力的な検索 (時計をチェックしてパターンを見つけます。タイムアウトになります。AC50%)
作る数が 0 になると、それは補われたことを意味します
。最初に p を使って補ってみます。補う数は mp になり
、次に q を使って補ってみます。 make up は mq になり、
補えない場合は false を返します
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;
int n,m,ans;
bool dfs(int m,int p,int q){
if(!m) return true;
if(m>=p&&dfs(m-p,p,q)) return true;
if(m>=q&&dfs(m-q,p,q)) return true;
return false;
}
int main(){
cin>>n>>m;
for(int i=1;i<=1000;i++){
if(!dfs(i,n,m)) ans=i;
}
cout<<ans<<endl;
return 0;
}
この暴力的な検索によると、次のようにテーブルを入力することでルールを見つけることができます。
3 2 1
3 4 5
3 5 7
3 7 11
3 8 13
n=3、m+1、ans+2 の場合、
ans=2m+x が
データに代入されて x=-3 が得られ、
式は ans=2m-3; (n= 3)
同様に、さらにいくつかの式をプッシュします
4 7 17
4 9 23
4 11 29
ans=3m-4(n=4)
最後に、ans=(n-1)*(m-1)-1の近似式が得られます。
方法 2. 式を使用して答えを直接出力します: (p-1)(q-1)-1
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int n,m;
int main(){
cin>>n>>m;
cout<<(n-1)*(m-1)-1<<endl;
return 0;
}