問題文↓
https://atcoder.jp/contests/abc006/tasks/abc006_3
diff1158
以下,大人の足の数、老人の足の数、子供の足の数をa,b,c
とあらわすことにする。
解法:a+b+c=n,2a+3b+4c=mとして不定方程式を解く。
まず、2n>mもしくは4n<mのときは明らかに達成できない。
そうではない場合について考えると、
a+b+c=nなので両辺を2倍して2a+2b+2c=2nといえる。
これを先ほどの式から引くとb+2c=m-2nとなる。
よって、b=(m-2n)%2,c=(m-2n)/2と表せ、a=n-b-cなのでa=n-(m-2n)%2-(m-2n)/2と表せる。
以下 c++コード↓
#include<bits/stdc++.h>
using namespace std;
int main(){
int n,m;cin >> n >> m;
if(2*n>m or 4*n<m)cout << "-1 -1 -1\n";
else cout << n-(m-2*n)%2-(m-2*n)/2 << " " << (m-2*n)%2 << " " << (m-2*n)/2 << '\n';
}
もっとシンプルにできないか考えてみる。
まずb (m-2n)%2となっているが、
2nは絶対に偶数なので、
(m-2n)%2=m%2 と表せる。
次にc これはやらなくてもいいが、一応括弧を外しておく
(m-2n)/2となっているが、
・mが奇数の時 m=2k+1とあらわすと(2k+1-2n)/2=k-n
・mが偶数の時 m=2kとあらわすと(2k-2n)/2=k-n
よってm/2-nと表せるとわかる。
最後にa これはn-m%2-(m/2-n)でもいいが,
4n-m=2a+bがいえるので、a=(4n-m)/2。
・mが奇数の時 m=2k+1と表すと(4n-m)/2=2n-k-1
・mが偶数の時 m=2kと表すと(4n-m)/2=2n-k
よって2n-(m+1)/2と表せるとわかる。
以下 c++コード↓
#include<bits/stdc++.h>
using namespace std;
int main(){
int n,m;cin >> n >> m;
if(2*n>m or 4*n<m)cout << "-1 -1 -1\n";
else cout << 2*n-(m+1)/2 << " " << m%2 << " " << m/2-n << '\n';
}
ちなみにこれをさらにbyte数を短くした以下のコードでこの問題のC++AC最短コードを達成できた。(2024/07/30時点)
#include<iostream>
using namespace std;int main(){int n,m;cin>>n>> m;if(2*n>m or 4*n<m)cout << "-1 -1 -1\n";else cout<<2*n-(m+1)/2<<" "<<m%2<<" "<<m/2-n<<'\n';}