Number of triangles that can be formed with given N points
Last Updated :
16 Mar, 2023
Given X and Y coordinates of N points on a Cartesian plane. The task is to find the number of possible triangles with the non-zero area that can be formed by joining each point to every other point.
Examples:
Input: P[] = {{0, 0}, {2, 0}, {1, 1}, {2, 2}}
Output: 3
Possible triangles can be [(0, 0}, (2, 0), (1, 1)],
[(0, 0), (2, 0), (2, 2)] and [(1, 1), (2, 2), (2, 0)]
Input : P[] = {{0, 0}, {2, 0}, {1, 1}}
Output : 1
A Naive approach has been already discussed in Number of possible Triangles in a Cartesian coordinate system
7Efficient Approach: Consider a point Z and find its slope with every other point. Now, if two points are having the same slope with point Z that means the 3 points are collinear and they cannot form a triangle. Hence, the number of triangles having Z as one of its points is the number of ways of choosing 2 points from the remaining points and then subtracting the number of ways of choosing 2 points from points having the same slope with Z. Since Z can be any point among N points, we have to iterate one more loop.
Steps to solve the problem:
- Initialize an empty map mp and a variable ans to 0.
- Iterate from 0 to N-1.
- Clear the map mp.
- For each point i, calculate the slope of all other points with respect to the current point.
- calculate the greatest common divisor (GCD) of the difference in X and Y coordinate
- between point i and j. Divide the difference in X and Y coordinates by their GCD.
- Store the slope as a key-value pair in the map mp, where the key is a pair of integers representing the slope and the value is the frequency of that slope.
- Calculate the number of ways by the formula (N – (i + 1)) * (N – (i + 1) – 1) / 2. Add this value to the and.
- Iterate over the map mp, and for each key-value pair, calculate the number of ways by the formula j.second * (j.second – 1) /2.
- Subtract this value from the and.
- Return the final value of ans.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int countTriangles(pair< int , int > P[], int N)
{
map<pair< int , int >, int > mp;
int ans = 0;
for ( int i = 0; i < N; i++) {
mp.clear();
for ( int j = i + 1; j < N; j++) {
int X = P[i].first - P[j].first;
int Y = P[i].second - P[j].second;
int g = __gcd(X, Y);
X /= g;
Y /= g;
mp[{ X, Y }]++;
}
int num = N - (i + 1);
ans += (num * (num - 1)) / 2;
for ( auto j : mp)
ans -= (j.second * (j.second - 1)) / 2;
}
return ans;
}
int main()
{
pair< int , int > P[] = { { 0, 0 }, { 2, 0 }, { 1, 1 }, { 2, 2 } };
int N = sizeof (P) / sizeof (P[0]);
cout << countTriangles(P, N) << endl;
return 0;
}
|
Java
import java.util.*;
class GFG {
static int __gcd( int x, int y)
{
x = Math.abs(x);
y = Math.abs(y);
while (y > 0 ) {
int t = y;
y = x % y;
x = t;
}
return x;
}
static int countTriangles( int [][] P, int N)
{
HashMap<String, Integer> mp
= new HashMap<String, Integer>();
int ans = 0 ;
for ( int i = 0 ; i < N; i++) {
mp.clear();
for ( int j = i + 1 ; j < N; j++) {
int X = P[i][ 0 ] - P[j][ 0 ];
int Y = P[i][ 1 ] - P[j][ 1 ];
int g = __gcd(X, Y);
X = ( int )(X / g);
Y = ( int )(Y / g);
String key = String.valueOf(X) + ","
+ String.valueOf(Y);
if (!mp.containsKey(key))
mp.put(key, 0 );
mp.put(key, mp.get(key) + 1 );
}
int num = N - (i + 1 );
ans += ( int )((num * (num - 1 )) / 2 );
for (Map.Entry<String, Integer> entry :
mp.entrySet())
ans -= (entry.getValue()
* (entry.getValue() - 1 ))
/ 2 ;
}
return ans;
}
public static void main(String[] args)
{
int [][] P
= { { 0 , 0 }, { 2 , 0 }, { 1 , 1 }, { 2 , 2 } };
int N = P.length;
System.out.println(countTriangles(P, N));
}
}
|
Python3
from collections import defaultdict
from math import gcd
def countTriangles(P, N):
mp = defaultdict( lambda : 0 )
ans = 0
for i in range ( 0 , N):
mp.clear()
for j in range (i + 1 , N):
X = P[i][ 0 ] - P[j][ 0 ]
Y = P[i][ 1 ] - P[j][ 1 ]
g = gcd(X, Y)
X / / = g
Y / / = g
mp[(X, Y)] + = 1
num = N - (i + 1 )
ans + = (num * (num - 1 )) / / 2
for j in mp:
ans - = (mp[j] * (mp[j] - 1 )) / / 2
return ans
if __name__ = = "__main__" :
P = [[ 0 , 0 ], [ 2 , 0 ], [ 1 , 1 ], [ 2 , 2 ]]
N = len (P)
print (countTriangles(P, N))
|
C#
using System;
using System.Collections.Generic;
class GFG {
static int __gcd( int x, int y)
{
x = Math.Abs(x);
y = Math.Abs(y);
while (y > 0) {
int t = y;
y = x % y;
x = t;
}
return x;
}
static int countTriangles( int [, ] P, int N)
{
Dictionary< string , int > mp
= new Dictionary< string , int >();
int ans = 0;
for ( int i = 0; i < N; i++) {
mp.Clear();
for ( int j = i + 1; j < N; j++) {
int X = P[i, 0] - P[j, 0];
int Y = P[i, 1] - P[j, 1];
int g = __gcd(X, Y);
X = ( int )(X / g);
Y = ( int )(Y / g);
int [] l1 = { X, Y };
string key = string .Join( ", " , l1);
if (!mp.ContainsKey(key))
mp[key] = 0;
mp[key]++;
}
int num = N - (i + 1);
ans += ( int )((num * (num - 1)) / 2);
foreach ( var entry in mp) ans
-= (entry.Value * (entry.Value - 1)) / 2;
}
return ans;
}
public static void Main( string [] args)
{
int [, ] P
= { { 0, 0 }, { 2, 0 }, { 1, 1 }, { 2, 2 } };
int N = P.GetLength(0);
Console.WriteLine(countTriangles(P, N));
}
}
|
Javascript
function __gcd(x, y) {
if (( typeof x !== 'number' ) || ( typeof y !== 'number' ))
return false ;
x = Math.abs(x);
y = Math.abs(y);
while (y) {
var t = y;
y = x % y;
x = t;
}
return x;
}
function countTriangles(P, N)
{
let mp = new Map();
let ans = 0;
for (let i = 0; i < N; i++) {
mp.clear();
for (let j = i + 1; j < N; j++) {
let X = P[i][0] - P[j][0];
let Y = P[i][1] - P[j][1];
let g = __gcd(X, Y);
X = Math.floor(X/g);
Y = Math.floor(Y/g);
if (mp.has([X, Y].join())){
mp.set([X, Y].join(), mp.get([X, Y].join()) + 1);
}
else {
mp.set([X, Y].join(), 1);
}
}
let num = N - (i + 1);
ans += Math.floor((num * (num - 1)) / 2);
for (const [key, value] of mp.entries())
ans -= (value * (value - 1)) / 2;
}
return ans;
}
let P = [[0, 0], [2, 0], [1, 1 ], [2, 2 ]];
let N = P.length;
console.log(countTriangles(P, N));
|
Time Complexity: O(N2logN)
Auxiliary Space: O(N)
Share your thoughts in the comments
Please Login to comment...