プログラマー-四段高音
2285 ワード
プログラマー-四段高音
コカソはテストボックスが打たれることがあるので、デバッグが不便です.
この問題は基本的にdfs+剪断問題である.
nが与えられた場合、その数値が問題で与えられた条件を満たす場合、nを生成できる状況がどれだけあるかを調べることができる.
問題は*+...などの文字列で、*は乗算3演算、+は加算1演算です.
*の後には2つの+演算があり、*は**++、*+*++などの形式で連続的に与えることができます.
1から*に遭遇すると3を掛け、+に遭遇すると1を掛ける.
例えば、**++は13を表す.
41を表すのは2つのケースがあります:**++*++、*+*+++.
解決策は以下の通り.最初にk個*で表される範囲の最大値は、k−1個*で表される範囲の最大値よりも常に大きく、k+1個*で表される範囲の最大値よりも小さい.すなわち,nが与えられると,k値がどれだけあるかがすぐに分かる. kが3の場合、****++++は最高値、*++*+++は最高値となる. nを表す文字列の最後の2つは常に++である. 上記の条件でdfsを回し、nが与えられたときにn−2からdfsを実行し、+が何回発生したか、*が何回発生したかを確認し、同時に剪断を実行する.
dfsを迂回する概念はnの値に基づいて逆方向に演算を追加する方式である.
すなわち、3を掛けると除法3になり、1を加えるとマイナス1になる.
たとえば、13を作成するには、
13 -> 12 -> 11 -> 10 -> 9 -> 8 ... -> 1
13 -> 12 -> 4 -> 3 -> 2 -> 1
13 -> 12 -> 4 -> 3 -> 1
等順で演算できるはずです.
このとき、*が3回発生したnであれば、+個の数は常に6未満でなければならず、*個の数は3未満でなければならない.
また、+の個数は*の個数の2倍を超えてはならず、nは常に1より大きくなければならない.
上記の条件に従って枝打ちを行い、条件に合致した場合にのみ、1の正解を増やすことができます.
コードは以下の通りです.
コカソはテストボックスが打たれることがあるので、デバッグが不便です.
この問題は基本的にdfs+剪断問題である.
nが与えられた場合、その数値が問題で与えられた条件を満たす場合、nを生成できる状況がどれだけあるかを調べることができる.
問題は*+...などの文字列で、*は乗算3演算、+は加算1演算です.
*の後には2つの+演算があり、*は**++、*+*++などの形式で連続的に与えることができます.
1から*に遭遇すると3を掛け、+に遭遇すると1を掛ける.
例えば、**++は13を表す.
41を表すのは2つのケースがあります:**++*++、*+*+++.
解決策は以下の通り.
dfsを迂回する概念はnの値に基づいて逆方向に演算を追加する方式である.
すなわち、3を掛けると除法3になり、1を加えるとマイナス1になる.
たとえば、13を作成するには、
13 -> 12 -> 11 -> 10 -> 9 -> 8 ... -> 1
13 -> 12 -> 4 -> 3 -> 2 -> 1
13 -> 12 -> 4 -> 3 -> 1
等順で演算できるはずです.
このとき、*が3回発生したnであれば、+個の数は常に6未満でなければならず、*個の数は3未満でなければならない.
また、+の個数は*の個数の2倍を超えてはならず、nは常に1より大きくなければならない.
上記の条件に従って枝打ちを行い、条件に合致した場合にのみ、1の正解を増やすことができます.
コードは以下の通りです.
#include <cstdio>
int answer;
void dfs(int high, int cur, int p, int m)
{
if(cur < 3)
return;
if(m > high)
return;
if(p > (high << 1))
return;
if((m << 1) > p)
return;
if(cur == 3 && ((m + 1) << 1) == p) {
answer++;
return;
}
if(cur % 3 == 0)
dfs(high, cur / 3, p, m + 1);
dfs(high, cur - 1, p + 1, m);
}
int solution(int n) {
if(n % 2 == 0)
return 0;
int high_note[20] = { 1 };
int tmp = -2;
for(int i=1;i<20;i++) {
high_note[i] = high_note[i - 1] * 3 - tmp;
tmp += 4;
}
int high = 19;
for(int i=1;i<20;i++)
if(n < high_note[i]) {
high = i - 1;
break;
}
answer = 0;
dfs(high, n - 2, 2, 0);
return answer;
}
Reference
この問題について(プログラマー-四段高音), 我々は、より多くの情報をここで見つけました https://velog.io/@gkak1121/프로그래머스-4단-고음テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol