HackerRank Lovely Triplets Problem Solution Yashwant Parihar, June 19, 2023August 1, 2024 In this post, we will solve HackerRank Lovely Triplets Problem Solution. Daniel loves graphs. He thinks a graph is special if it has the following properties: It is undirected. The length of each edge is 1. It includes exactly P different lovely triplets.A triplet is a set of 3 different nodes. A triplet is lovely if the minimum distance between each pair of nodes in the triplet is exactly Q. Two triplets are different if 1 or more of their component nodes are different.Given P and Q. help Daniel draw a special graph.Input FormatA single line containing 2 space-separated integers, P (the number of different lovely triplets you must have in your graph) and Q (the required distance between each pair of nodes in a lovely triplet), respectively. Output FormatFor the first line, print 2 space-separated integers, N (the number of nodes in the graph) and M (the number of edges in the graph), respectively.On each line i of the M subsequent lines, print two space-separated integers, u, and v describing an edge between nodes u, and .Your output must satisfy the following conditions:0 < N, M≤ 100 1 < uj, vj ≤ NIf there is more than one correct answer, print any one of them. Sample Input 3 2 Sample Output 7 7 1 2 2 3 3 4 4 5 5 6 6 1 1 7 HackerRank Lovely Triplets Problem Solution Lovely Triplets C Solution #include <assert.h> #include <limits.h> #include <math.h> #include <stdbool.h> #include <stddef.h> #include <stdint.h> #include <stdio.h> #include <stdlib.h> #include <string.h> char* readline(); char** split_string(char*); int** makeGraph(int p, int q, int startv, int *result_count){ if(p == 0){ *result_count = 1; int** toreturn = malloc(sizeof(int*)); toreturn[0] = malloc(2*sizeof(int)); toreturn[0][0] = 0; toreturn[0][1] = 0; return toreturn; } if(q == 2){ int numspokes = 3; while(numspokes*(numspokes - 1)*(numspokes - 2) <= 6*p){ numspokes++; } numspokes--; int tempresult_count; int** graph = makeGraph(p - (numspokes*(numspokes - 1)*(numspokes - 2))/6, q, startv + 1 + numspokes, &tempresult_count); *result_count = tempresult_count + numspokes; graph = realloc(graph, (*result_count)*sizeof(int*)); for(int i = 0; i < numspokes; i++){ graph[tempresult_count + i] = malloc(2*sizeof(int)); graph[tempresult_count + i][0] = startv + 1; graph[tempresult_count + i][1] = startv + i + 2; } graph[0][0] += numspokes + 1; graph[0][1] += numspokes; return graph; } else{ int factor1[q - 2]; int factor2[q - 2]; int factor3[q - 2]; int currp = p; int extranum = 3*(q - 2); for(int i = 0; i < q - 2; i++){ if(currp == 0){ factor1[i] = 0; factor2[i] = 0; factor3[i] = 0; } else{ factor1[i] = 1; while(factor1[i]*factor1[i]*factor1[i] <= currp){ factor1[i]++; } factor1[i]--; factor2[i] = factor1[i]; while(factor1[i]*factor2[i]*factor2[i] <= currp){ factor2[i]++; } factor2[i]--; factor3[i] = factor2[i]; while(factor1[i]*factor2[i]*factor3[i] <= currp){ factor3[i]++; } factor3[i]--; currp -= factor1[i]*factor2[i]*factor3[i]; extranum += factor1[i] + factor2[i] + factor3[i]; } } int tempresult_count; int** graph = makeGraph(currp, q, startv + extranum, &tempresult_count); *result_count = tempresult_count + extranum; graph = realloc(graph, (*result_count)*sizeof(int*)); graph[tempresult_count] = malloc(2*sizeof(int)); graph[tempresult_count][0] = startv + 1; graph[tempresult_count][1] = startv + 3*(q - 2); for(int i = 0; i < 3*(q - 2) - 1; i++){ graph[tempresult_count + i + 1] = malloc(2*sizeof(int)); graph[tempresult_count + i + 1][0] = startv + i + 1; graph[tempresult_count + i + 1][1] = startv + i + 2; } int index = tempresult_count + 3*(q - 2); int numvertex = 3*(q - 2); for(int i = 0; i < q - 2; i++){ for(int j = 0; j < factor1[i]; j++){ graph[index] = malloc(2*sizeof(int)); graph[index][0] = startv + i + 1; graph[index][1] = startv + numvertex + 1; index++; numvertex++; } for(int j = 0; j < factor2[i]; j++){ graph[index] = malloc(2*sizeof(int)); graph[index][0] = startv + (q - 2) + i + 1; graph[index][1] = startv + numvertex + 1; index++; numvertex++; } for(int j = 0; j < factor3[i]; j++){ graph[index] = malloc(2*sizeof(int)); graph[index][0] = startv + 2*(q - 2) + i + 1; graph[index][1] = startv + numvertex + 1; index++; numvertex++; } } graph[0][0] += extranum; graph[0][1] += extranum; return graph; } } int main() { char** PQ = split_string(readline()); char* P_endptr; char* P_str = PQ[0]; int P = strtol(P_str, &P_endptr, 10); if (P_endptr == P_str || *P_endptr != '\0') { exit(EXIT_FAILURE); } char* Q_endptr; char* Q_str = PQ[1]; int Q = strtol(Q_str, &Q_endptr, 10); if (Q_endptr == Q_str || *Q_endptr != '\0') { exit(EXIT_FAILURE); } int result_count; int** result = makeGraph(P, Q, 0, &result_count); for(int i = 0; i < result_count; i++){ printf("%d %d\n", result[i][0], result[i][1]); } } char* readline() { size_t alloc_length = 1024; size_t data_length = 0; char* data = malloc(alloc_length); while (true) { char* cursor = data + data_length; char* line = fgets(cursor, alloc_length - data_length, stdin); if (!line) { break; } data_length += strlen(cursor); if (data_length < alloc_length - 1 || data[data_length - 1] == '\n') { break; } size_t new_length = alloc_length << 1; data = realloc(data, new_length); if (!data) { break; } alloc_length = new_length; } if (data[data_length - 1] == '\n') { data[data_length - 1] = '\0'; } data = realloc(data, data_length); return data; } char** split_string(char* str) { char** splits = NULL; char* token = strtok(str, " "); int spaces = 0; while (token) { splits = realloc(splits, sizeof(char*) * ++spaces); if (!splits) { return splits; } splits[spaces - 1] = token; token = strtok(NULL, " "); } return splits; } Lovely Triplets C++ Solution /* nice editorial !! */ #include <bits/stdc++.h> //#define debug #define fie(i,start,stop) for ( int i = start ; i < stop ; i ++ ) #define f first #define s second #define pii pair < int , int > #define vpii vector < pii > #define vi vector < int > #define pb push_back #define mp make_pair using namespace std ; vpii nc3 ; vi x ( 5001 , INT_MAX ) ; vi y ( 5001 , INT_MAX ) ; vi z ( 5001 , INT_MAX ) ; vpii dp ( 5001 , mp ( INT_MAX , INT_MAX ) ) ; int nc3_size = 0 ; int p , d , n = 0 , m = 0 ; vpii edges ( 100 ) ; int l , mid , r ; void build_even () { #ifdef debug cout << "building even" << endl ; #endif int root = n + 1 ; int nodes = ( d - 2 ) / 2 ; edges [ m ].f = n + 1 ; edges [ m ++ ].s = n + 2 ; fie ( i , 0 , nodes - 1 ) { edges [ m ].f = n + i + 2 ; edges [ m ++ ].s = n + i + 3 ; } n += nodes + 1 ; l = n ; edges [ m ].f = root ; edges [ m ++ ].s = n + 1 ; fie ( i , 0 , nodes - 1 ) { edges [ m ].f = n + i + 1 ; edges [ m ++ ].s = n + i + 2 ; } n += nodes ; mid = n ; edges [ m ].f = root ; edges [ m ++ ].s = n + 1 ; fie ( i , 0 , nodes - 1 ) { edges [ m ].f = n + i + 1 ; edges [ m ++ ].s = n + i + 2 ; } n += nodes ; r = n ; } void build_odd () { #ifdef debug cout << "building odd" << endl ; #endif if ( d == 3 ) { edges [ m ].f = n + 1 ; edges [ m ++ ].s = n + 2 ; edges [ m ].f = n + 1 ; edges [ m ++ ].s = n + 3 ; edges [ m ].f = n + 2 ; edges [ m ++ ].s = n + 3 ; l = n + 1 ; mid = n + 2 ; r = n + 3 ; n += 3 ; return ; } int nodes = ( d - 3 ) / 2 ; int root1 = n + 1 ; edges [ m ].f = n + 1 ; edges [ m ++ ].s = n + 2 ; fie ( i , 0 , nodes - 1 ) { edges [ m ].f = n + i + 2 ; edges [ m ++ ].s = n + i + 3 ; } n += nodes + 1 ; l = n ; int root2 = n + 1 ; edges [ m ].f = n + 1 ; edges [ m ++ ].s = n + 2 ; fie ( i , 0 , nodes - 1 ) { edges [ m ].f = n + i + 2 ; edges [ m ++ ].s = n + i + 3 ; } n += nodes + 1 ; mid = n ; int root3 = n + 1 ; edges [ m ].f = n + 1 ; edges [ m ++ ].s = n + 2 ; fie ( i , 0 , nodes - 1 ) { edges [ m ].f = n + i + 2 ; edges [ m ++ ].s = n + i + 3 ; } n += nodes + 1 ; r = n ; edges [ m ].f = root1 ; edges [ m ++ ].s = root2 ; edges [ m ].f = root1 ; edges [ m ++ ].s = root3 ; edges [ m ].f = root2 ; edges [ m ++ ].s = root3 ; } void add_edge ( int no_l , int no_mid , int no_r ) { #ifdef debug cout << "adding edge " << no_l << " " << no_mid << " " << no_r << endl ; #endif if ( d % 2 ) { build_odd () ; } else { build_even () ; } fie ( i , 0 , no_l ) { edges [ m ].f = l ; edges [ m ++ ].s = n + i + 1 ; } n += no_l ; fie ( i , 0 , no_mid ) { edges [ m ].f = mid ; edges [ m ++ ].s = n + i + 1 ; } n += no_mid ; fie ( i , 0 , no_r ) { edges [ m ].f = r ; edges [ m ++ ].s = n + i + 1 ; } n += no_r ; } void solve () { while ( p ) { #ifdef debug cout << "component of size " << dp [ p ].f << endl ; #endif add_edge ( x [ dp [ p ].f ] , y [ dp [ p ].f ] , z [ dp [ p ].f ] ) ; p -= dp [ p ].f ; } } void add_edge2 ( int no_of_nodes ) { #ifdef debug cout << "adding edge for dist 2 " << no_of_nodes << endl ; #endif fie ( i , 0 , no_of_nodes ) { edges [ m ].f = n + 1 ; edges [ m ++ ].s = n + i + 2 ; } n += no_of_nodes + 1 ; } void solve2 () { int idx = nc3_size - 1 ; while ( p ) { if ( nc3 [ idx ].f <= p ) { add_edge2 ( nc3 [ idx ].s ) ; p -= nc3 [ idx ].f ; } else { idx -- ; } } } void precal () { fie ( i , 1 , 100 ) { fie ( j , i , 100 ) { if ( i * j > 5000 || i + j > 93 ) { break ; } fie ( k , j , 100 ) { if ( i * j * k > 5000 || i + j + k > 94 ) { break ; } int mul = i * j * k ; if ( x [ mul ] == INT_MAX || ( ( x [ mul ] + y [ mul ] + z [ mul ] ) > ( i + j + k ) ) ) { x [ mul ] = i ; y [ mul ] = j ; z [ mul ] = k ; } } } } fie ( i , 0 , 5001 ) { fie ( j , 1 , 5001 ) { if ( i + j <= 5000 && x [ j ] != INT_MAX && ( dp [ i + j ].s > dp [ i ].s + x [ j ] + y [ j ] + z [ j ] ) ) { dp [ i + j ].f = j ; dp [ i + j ].s = dp [ i ].s + x [ j ] + y [ j ] + z [ j ] ; } } } int no = 3 ; while ( true ) { int prod = no * ( no - 1 ) * ( no - 2 ) ; prod /= 6 ; if ( prod <= 5000 ) { nc3.pb ( mp ( prod , no ++ ) ) ; #ifdef debug //cout << "nc3 " << no - 1 << " " << prod << endl ; #endif } else { break ; } } nc3_size = nc3.size () ; } int main () { precal () ; cin >> p >> d ; if ( d == 2 ) { solve2 () ; } else { solve () ; } cout << n << " " << m << endl ; fie ( i , 0 , m ) { cout << edges [ i ].f << " " << edges [ i ].s << endl ; } return 0 ; } Lovely Triplets C Sharp Solution using Newtonsoft.Json; using Newtonsoft.Json.Linq; using System; using System.Collections.Generic; using System.Diagnostics; using System.Dynamic; using System.Globalization; using System.IO; using System.Linq; using System.Media; using System.Reflection; using System.Security.AccessControl; using System.Text; using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; namespace _mtTest.ABC { class Program { public static void Main() { new Program().Run(); } class CGraph { public int V { get; set; } = 0; public List<int[]> E { get; set; } = new List<int[]>(); } int Product(IEnumerable<int> xs) { var y = 1; foreach (var x in xs) { y *= x; } return y; } static IEnumerable<int> GeneratePrimes(int n) { var p = new bool[n + 1]; for (int i = 0; i < p.Length; i++) { p[i] = true; } p[0] = false; p[1] = false; for (int i = 0; i < p.Length; i++) { if (!p[i]) continue; yield return i; for (int j = 2 * i; j <= n; j += i) p[j] = false; } } List<int> _primes = GeneratePrimes(5000).ToList(); IEnumerable<int> Factorize(int n) { List<int> qs = new List<int>(); foreach (var p in _primes) { if (p * p > n) break; while (n % p == 0) { qs.Add(p); n /= p; } } if (n != 1) qs.Add(n); return qs; } int CoreSize(int q) { var v1 = q % 2 == 1 ? 3 : 1; var v2 = q / 2 - 1; return v1 + v2; } Tuple<int[], int> SelectFactors(int p, int q, int width, Dictionary<int, Tuple<int[], int>> memo) { if (p == 0) return Tuple.Create(new[] { 0, 0, 0 }, 0); if (memo.ContainsKey(p)) return memo[p]; var qs = new[] { p, 1, 1 }; var qv = CoreSize(q) + qs.Sum(); var minWP = Math.Min(width, p); for (int i = 0; i < minWP; i++) { var ps = new[] { 1, 1, 1 }; var factors = Factorize(p - i); foreach (var r in factors) { var minIndex = 0; var minValue = ps.Min(); for (int k = 0; k < ps.Length; k++) { if (ps[k] != minValue) continue; minIndex = k; break; } ps[minIndex] *= r; } var pv = CoreSize(q) + ps.Sum(); var npv = SelectFactors(p - Product(ps), q, width, memo).Item2; pv += npv; if (pv < qv) { qs = ps; qv = pv; } } memo[p] = Tuple.Create(qs, qv); return memo[p]; } void BuildCoreQN(CGraph graph, int q, int[] ps) { int[] xs; if (q % 2 == 1) { xs = new[] { graph.V, graph.V + 1, graph.V + 2 }; graph.V += 3; for (int i = 0; i < 3; i++) { graph.E.Add(new[] { xs[i], xs[(i + 1) % 3] }); } } else { xs = new[] { graph.V, graph.V, graph.V }; graph.V += 1; } for (int i = 0; i < 3; i++) { for (int j = 0; j < q / 2 - 1; j++) { graph.E.Add(new[] { xs[i], graph.V }); xs[i] = graph.V; graph.V += 1; } } for (int i = 0; i < 3; i++) { for (int j = 0; j < ps[i]; j++) { graph.E.Add(new[] { xs[i], graph.V }); graph.V++; } } } void BuildCoreQ2(CGraph graph, int vLocal) { for (int i = 0; i < vLocal; i++) { graph.E.Add(new[] { graph.V, graph.V + i + 1 }); } graph.V += vLocal + 1; } void Run() { var inputs = Console.ReadLine().Split(' ').Select(x => int.Parse(x)).ToList(); var p = inputs[0]; var q = inputs[1]; CGraph graph = new CGraph(); if (q == 2) { Func<int, int> combination3 = n => n * (n - 1) * (n - 2) / 6; while (p > 0) { var vLocalIsolated = 3; while (true) { var pDiff = combination3(vLocalIsolated + 1); if (pDiff > p) break; vLocalIsolated++; } p -= combination3(vLocalIsolated); BuildCoreQ2(graph, vLocalIsolated); } } else { while (p > 0) { var factors = SelectFactors(p, q, width: 500, memo: new Dictionary<int, Tuple<int[], int>>()); var ps = factors.Item1; BuildCoreQN(graph, q, ps); p -= Product(ps); } } PrintGraph(graph); Console.WriteLine(); //CheckGraph(q, graph); } //static void CheckGraph(int q, CGraph cgraph) //{ // var graph = new Graph() { Q = q }; // foreach (var ei in cgraph.E) // { // graph.AddEdge(ei[0] + 1, ei[1] + 1); // } // Console.WriteLine(graph.GetTripletsCount()); //} static void PrintGraph(CGraph cgraph) { Console.WriteLine($"{cgraph.V} {cgraph.E.Count}"); foreach (var ei in cgraph.E) { Console.WriteLine($"{ei[0] + 1} {ei[1] + 1}"); } } //public void RunX() //{ // var graph = new Graph() { Q = 2 }; // graph.AddEdge(1, 2); // graph.AddEdge(1, 3); // graph.AddEdge(1, 4); // graph.AddEdge(1, 5); // graph.AddEdge(1, 6); // graph.AddEdge(1, 7); // graph.AddEdge(1, 8); // //graph.AddEdge(1, 5); // Console.WriteLine(graph.GetTripletsCount()); //} } } //graph.AddEdge(1, 2); //graph.AddEdge(2, 3); //graph.AddEdge(3, 4); //graph.AddEdge(4, 5); //graph.AddEdge(5, 6); //graph.AddEdge(6, 1); //graph.AddEdge(1, 7); //graph.AddEdge(7, 5); Lovely Triplets Java Solution import java.io.*; import java.util.*; import java.text.*; import java.math.*; import java.util.regex.*; public class LovelyTriplets { public static void main(String[] args) throws Exception { Scanner in = new Scanner(System.in); int cases = 1;//in.nextInt(); for (int testcase = 0; testcase < cases; testcase++) { int n = in.nextInt(); int m = in.nextInt(); lovelyTriplets(n, m); } } public static void lovelyTriplets(int n, int q) { if (q == 2) { lovelyTripletsTwo(n); return; } if (q == 3) { lovelyTripletsThree(n); return; } int best = Integer.MAX_VALUE; int bestIndex = -1; for (int i = 1; i < n; i++) { int[] b1 = bestThree(i); int[] b2 = bestThree(n-i); int sum = b1[0] +b1[1] + b1[2] + b2[0] + b2[1] + b2[2]; if (sum < best) { best = sum; bestIndex = i; } } int[] b1 = bestThree(bestIndex); int[] b2 = bestThree(n-bestIndex); int sum = 0; for (int i : b1) sum+=i; for (int i : b2) sum+=i; int nodes = sum+3*(q-2); System.out.println(nodes + " " + nodes); int node = 7; for (int i = 0; i < b1[0]; i++) { System.out.println("1 " + node); node++; } for (int i = 0; i < b1[1]; i++) { System.out.println("2 " + node); node++; } for (int i = 0; i < b1[2]; i++) { System.out.println("3 " + node); node++; } for (int i = 0; i < b2[0]; i++) { System.out.println("4 " + node); node++; } for (int i = 0; i < b2[1]; i++) { System.out.println("5 " + node); node++; } for (int i = 0; i < b2[2]; i++) { System.out.println("6 " + node); node++; } System.out.println("1 4"); System.out.println("2 5"); System.out.println("3 6"); int[] lasts = new int[]{4,5,6}; for (int i = 5; i <= q; i++) { for (int j = 0; j < 3; j++) { System.out.println(lasts[j] + " " + node); lasts[j] = node; node++; } } System.out.println(lasts[0] + " 2"); System.out.println(lasts[1] + " 3"); System.out.println(lasts[2] + " 1"); } static void lovelyTripletsThree(int n) { int best = Integer.MAX_VALUE; int bestIndex = -1; for (int i = 1; i < n; i++) { int[] b1 = bestThree(i); int[] b2 = bestThree(n-i); int sum = b1[0] +b1[1] + b1[2] + b2[0] + b2[1] + b2[2]; if (sum < best) { best = sum; bestIndex = i; } } int[] b1 = bestThree(bestIndex); int[] b2 = bestThree(n-bestIndex); int sum = 0; for (int i : b1) sum+=i; for (int i : b2) sum+=i; int nodes = sum+6; System.out.println(nodes + " " + nodes); int node = 7; for (int i = 0; i < b1[0]; i++) { System.out.println("1 " + node); node++; } for (int i = 0; i < b1[1]; i++) { System.out.println("2 " + node); node++; } for (int i = 0; i < b1[2]; i++) { System.out.println("3 " + node); node++; } for (int i = 0; i < b2[0]; i++) { System.out.println("4 " + node); node++; } for (int i = 0; i < b2[1]; i++) { System.out.println("5 " + node); node++; } for (int i = 0; i < b2[2]; i++) { System.out.println("6 " + node); node++; } System.out.println("1 2"); System.out.println("2 3"); System.out.println("3 1"); System.out.println("4 5"); System.out.println("5 6"); System.out.println("6 4"); } static int[] bestThree(int n) { int cube = (int)Math.pow(n, 1.0/3.0); for (int i = cube+1; i >= 1; i--) { if ((n%i) == 0) { int[] bt = bestTwo(n/i); return new int[]{i, bt[0], bt[1]}; } } return new int[]{n, 1, 1}; } static int[] bestTwo(int n) { int square = (int)Math.sqrt(n); for (int i = square+1; i >= 1; i--) { if ((n%i) == 0) { return new int[]{i, n/i}; } } return new int[]{n, 1}; } public static void lovelyTripletsTwo(int p) { int[] chooses = new int[34]; for (int i = 3; i < 34; i++) { int val = i*(i-1)*(i-2)/6; chooses[i] = val; } int total = 0; List<Integer> flowers = new ArrayList<Integer>(); while (total < p) { for (int i = 33; i >= 3; i--) { if (total + chooses[i] <= p) { total += chooses[i]; flowers.add(i); i++; } } } int numFlowers = flowers.size(); int numLeaves = 0; for (int flower : flowers) numLeaves += flower; System.out.println((numFlowers + numLeaves) + " " + numLeaves); int nodeCount = 0; for (int flower : flowers) { int root = nodeCount+1; for (int i = 0; i < flower; i++) { System.out.println(root + " " + (root+i+1)); } nodeCount = root + flower; } } } Lovely Triplets JavaScript Solution process.stdin.resume(); process.stdin.setEncoding('ascii'); var input_stdin = ""; var input_stdin_array = ""; var input_currentline = 0; process.stdin.on('data', function (data) { input_stdin += data; }); process.stdin.on('end', function () { input_stdin_array = input_stdin.split("\n"); main(); }); function readLine() { return input_stdin_array[input_currentline++]; } function main() { var P_temp = readLine().split(' '); var P = parseInt(P_temp[0]); var Q = parseInt(P_temp[1]); var N = 0; var M = 0; var E = [] if (Q == 2) { while ( P > 0 ) { var hub = N; var spars = 0 N++; E.push([hub,N]); N++; M++; spars++; E.push([hub,N]); N++; M++; spars++; E.push([hub,N]); N++; M++; spars++; P--; while ((spars*(spars-1)/2) <= P) { P -= (spars*(spars-1)/2); E.push([hub,N]); N++; M++; spars++; } } } else { while ( P>0) { var start = N; N++; for (var j=1; j<3*(Q-2); j++) { E.push([start+j-1,start+j]); M++; N++; } E.push([start+(3*(Q-2))-1,start]); M++; var nub = 0; while (P>0 && nub < Q-2) { var spars_0 = 0; var spars_1 = 0; var spars_2 = 0; while (P >= (spars_0+1)*(spars_1+1)*(spars_2+1)) { E.push([start+nub,N]); N++; M++; spars_0++; E.push([start+nub+Q-2,N]); N++; M++; spars_1++; E.push([start+nub+Q+Q-4,N]); N++; M++; spars_2++; } while (P >= (spars_0+1)*(spars_1+1)*(spars_2)) { E.push([start+nub,N]); N++; M++; spars_0++; E.push([start+nub+Q-2,N]); N++; M++; spars_1++; } while (P >= (spars_0+1)*(spars_1)*(spars_2)) { E.push([start+nub,N]); N++; M++; spars_0++; } P -= spars_0*spars_1*spars_2 nub++; } } } console.log([N,M].join(' ')); for(var i=0; i<M; i++) { console.log(E[i].map(x=>x+1).join(' ')); } } Lovely Triplets Python Solution #!/usr/bin/env python3 def choose(n, r): return n * (n-1) * (n-2) // (r * (r-1) * (r-2)) def product(xs): y = 1 for x in xs: y *= x return y def generate_primes(n): p = [True] * (n + 1) p[0] = False p[1] = False for i in range(n+1): if p[i]: yield i for j in range(2*i,n+1,i): p[j] = False primes = list(generate_primes(5000)) def factorize(n): qs = [] for p in primes: if p*p > n: break while n % p == 0: qs.append(p) n //= p if n != 1: qs.append(n) return qs def core_size(q): return ((q - 1) // 2) * 3 def select_factors(p, q, width, memo): if p in memo: return memo[p] qs = [p, 1, 1] qv = core_size(q) + sum(qs) for i in range(min(width, p)): ps = [1, 1, 1] for r in factorize(p - i): ps[ps.index(min(ps))] *= r pv = core_size(q) + sum(ps) if i: nps, npv = select_factors(p - product(ps), q, width=width, memo=memo) pv += npv if pv < qv: qs = ps qv = pv memo[p] = (tuple(qs), qv) return memo[p] def make_core(v, e, q): if q % 2 == 1: xs, v = [v, v+1, v+2], v+3 for i in range(3): e.append((xs[i], xs[(i+1)%3])) else: xs, v = [v, v, v], v+1 for i in range(3): for j in range(q//2 - 1): e.append((xs[i], v)) xs[i] = v v += 1 return xs, v def make_triplets(v, e, q, ps): xs, v = make_core(v, e, q) for i in range(3): for _ in range(ps[i]): e.append((xs[i], v)) v += 1 return v def make_coalesced_core(v, e, l): for i in range(l): e.append((v, v + i+1)) v += l+1 return v p, q = map(int,input().split()) v = 0 e = [] if q == 2: while p: l = 3 while choose(l+1,3) <= p: l += 1 p -= choose(l,3) v = make_coalesced_core(v, e, l) else: while p: ps, _ = select_factors(p, q, width=500, memo={}) v = make_triplets(v, e, q, ps) p -= product(ps) print(v, len(e)) assert v <= 100 for a, b in e: print(a+1, b+1) c C# C++ HackerRank Solutions java javascript python CcppCSharpHackerrank Solutionsjavajavascriptpython