양수 N이 주어지면 단계가 N을 (N-1)로 변환하거나 N을 더 큰 제수 중 하나로 변환하는 것으로 정의되는 최소 단계 수에서 1에 도달해야 합니다.
공식적으로 우리가 N에 있다면 1단계로 (N - 1)에 도달할 수 있고, N = u*v이면 u > 1이고 v > 1인 max(u v)에 도달할 수 있습니다.
예:
Input : N = 17 Output : 4 We can reach to 1 in 4 steps as shown below 17 -> 16(from 17 - 1) -> 4(from 4 * 4) -> 2(from 2 * 2) -> 1(from 2 - 1) Input : N = 50 Output : 5 We can reach to 1 in 5 steps as shown below 50 -> 10(from 5 * 10) -> 5(from 2 * 5) -> 4(from 5 - 1) -> 2(from 2 *2) -> 1(from 2 - 1)
이 문제는 레벨별로 작동하므로 N의 다음 레벨에 (N - 1)과 N의 더 큰 고유 인수가 포함되는 최소 단계 수에서 1에 도달하기 때문에 너비 우선 검색을 사용하여 이 문제를 해결할 수 있습니다.
완전한 BFS 절차는 다음과 같습니다. 먼저 0단계의 N을 데이터 큐에 푸시한 다음 각 레벨에서 이전 레벨 요소보다 1단계 더 많은 다음 레벨 요소를 푸시합니다. 이런 방식으로 1이 대기열에서 튀어나오면 여기에는 최종 결과가 될 최소 단계 수가 포함됩니다.
아래 코드에서는 N의 값과 단계를 저장하는 '데이터' 유형 구조의 큐가 사용되며, 동일한 요소를 두 번 이상 푸시하여 무한 루프로 이어질 수 있는 것을 방지하기 위해 또 다른 정수 유형 세트가 사용됩니다. 따라서 각 단계에서 값이 두 번 이상 방문되지 않도록 값을 대기열에 넣은 후 값을 세트로 밀어 넣습니다.
더 나은 이해를 위해 아래 코드를 참조하십시오.
C++// C++ program to get minimum step to reach 1 // under given constraints #include using namespace std; // structure represent one node in queue struct data { int val; int steps; data(int val int steps) : val(val) steps(steps) {} }; // method returns minimum step to reach one int minStepToReachOne(int N) { queue<data> q; q.push(data(N 0)); // set is used to visit numbers so that they // won't be pushed in queue again set<int> st; // loop until we reach to 1 while (!q.empty()) { data t = q.front(); q.pop(); // if current data value is 1 return its // steps from N if (t.val == 1) return t.steps; // check curr - 1 only if it not visited yet if (st.find(t.val - 1) == st.end()) { q.push(data(t.val - 1 t.steps + 1)); st.insert(t.val - 1); } // loop from 2 to sqrt(value) for its divisors for (int i = 2; i*i <= t.val; i++) { // check divisor only if it is not visited yet // if i is divisor of val then val / i will // be its bigger divisor if (t.val % i == 0 && st.find(t.val / i) == st.end()) { q.push(data(t.val / i t.steps + 1)); st.insert(t.val / i); } } } } // Driver code to test above methods int main() { int N = 17; cout << minStepToReachOne(N) << endl; }
Java // Java program to get minimum step to reach 1 // under given constraints import java.util.*; class GFG { // structure represent one node in queue static class data { int val; int steps; public data(int val int steps) { this.val = val; this.steps = steps; } }; // method returns minimum step to reach one static int minStepToReachOne(int N) { Queue<data> q = new LinkedList<>(); q.add(new data(N 0)); // set is used to visit numbers so that they // won't be pushed in queue again HashSet<Integer> st = new HashSet<Integer>(); // loop until we reach to 1 while (!q.isEmpty()) { data t = q.peek(); q.remove(); // if current data value is 1 return its // steps from N if (t.val == 1) return t.steps; // check curr - 1 only if it not visited yet if (!st.contains(t.val - 1)) { q.add(new data(t.val - 1 t.steps + 1)); st.add(t.val - 1); } // loop from 2 to Math.sqrt(value) for its divisors for (int i = 2; i*i <= t.val; i++) { // check divisor only if it is not visited yet // if i is divisor of val then val / i will // be its bigger divisor if (t.val % i == 0 && !st.contains(t.val / i) ) { q.add(new data(t.val / i t.steps + 1)); st.add(t.val / i); } } } return -1; } // Driver code public static void main(String[] args) { int N = 17; System.out.print(minStepToReachOne(N) +'n'); } } // This code is contributed by 29AjayKumar
Python3 # Python3 program to get minimum step # to reach 1 under given constraints # Structure represent one node in queue class data: def __init__(self val steps): self.val = val self.steps = steps # Method returns minimum step to reach one def minStepToReachOne(N): q = [] q.append(data(N 0)) # Set is used to visit numbers # so that they won't be pushed # in queue again st = set() # Loop until we reach to 1 while (len(q)): t = q.pop(0) # If current data value is 1 # return its steps from N if (t.val == 1): return t.steps # Check curr - 1 only if # it not visited yet if not (t.val - 1) in st: q.append(data(t.val - 1 t.steps + 1)) st.add(t.val - 1) # Loop from 2 to Math.sqrt(value) # for its divisors for i in range(2 int((t.val) ** 0.5) + 1): # Check divisor only if it is not # visited yet if i is divisor of val # then val / i will be its bigger divisor if (t.val % i == 0 and (t.val / i) not in st): q.append(data(t.val / i t.steps + 1)) st.add(t.val / i) return -1 # Driver code N = 17 print(minStepToReachOne(N)) # This code is contributed by phasing17
C# // C# program to get minimum step to reach 1 // under given constraints using System; using System.Collections.Generic; class GFG { // structure represent one node in queue class data { public int val; public int steps; public data(int val int steps) { this.val = val; this.steps = steps; } }; // method returns minimum step to reach one static int minStepToReachOne(int N) { Queue<data> q = new Queue<data>(); q.Enqueue(new data(N 0)); // set is used to visit numbers so that they // won't be pushed in queue again HashSet<int> st = new HashSet<int>(); // loop until we reach to 1 while (q.Count != 0) { data t = q.Peek(); q.Dequeue(); // if current data value is 1 return its // steps from N if (t.val == 1) return t.steps; // check curr - 1 only if it not visited yet if (!st.Contains(t.val - 1)) { q.Enqueue(new data(t.val - 1 t.steps + 1)); st.Add(t.val - 1); } // loop from 2 to Math.Sqrt(value) for its divisors for (int i = 2; i*i <= t.val; i++) { // check divisor only if it is not visited yet // if i is divisor of val then val / i will // be its bigger divisor if (t.val % i == 0 && !st.Contains(t.val / i) ) { q.Enqueue(new data(t.val / i t.steps + 1)); st.Add(t.val / i); } } } return -1; } // Driver code public static void Main(String[] args) { int N = 17; Console.Write(minStepToReachOne(N) +'n'); } } // This code is contributed by 29AjayKumar
JavaScript <script> // Javascript program to get minimum step // to reach 1 under given constraints // Structure represent one node in queue class data { constructor(val steps) { this.val = val; this.steps = steps; } } // Method returns minimum step to reach one function minStepToReachOne(N) { let q = []; q.push(new data(N 0)); // Set is used to visit numbers // so that they won't be pushed // in queue again let st = new Set(); // Loop until we reach to 1 while (q.length != 0) { let t = q.shift(); // If current data value is 1 // return its steps from N if (t.val == 1) return t.steps; // Check curr - 1 only if // it not visited yet if (!st.has(t.val - 1)) { q.push(new data(t.val - 1 t.steps + 1)); st.add(t.val - 1); } // Loop from 2 to Math.sqrt(value) // for its divisors for(let i = 2; i*i <= t.val; i++) { // Check divisor only if it is not // visited yet if i is divisor of val // then val / i will be its bigger divisor if (t.val % i == 0 && !st.has(t.val / i)) { q.push(new data(t.val / i t.steps + 1)); st.add(t.val / i); } } } return -1; } // Driver code let N = 17; document.write(minStepToReachOne(N) + '
'); // This code is contributed by rag2127 </script>
산출:
4