https://www.hackerrank.com/challenges/stars
Problem Statement from the hacker rank
Little John has drawn N stars on his paper where each star has a weight vi . He draws a straight line that divides the paper into two parts such that each part has a subset of stars in them. Let the weight of each part be the summation of weights of the stars in the part. He wants to draw the line such that the difference in the sum of weights between the two parts is as small as possible while maximizing the smaller part's weight.
Your task is to compute the weight of smaller part corresponding to this line where no stars are allowed to be on the line and line can be of any slope.
Input Format
The first line of the input contains an integerN .
Each of nextN lines contains three integers xi and yi specifying the positions of ith star and vi .
No three points lie on a line.
The first line of the input contains an integer
Each of next
No three points lie on a line.
The key here is the formular to find if point is on left or right side of a line:
position = sign( (Bx-Ax)*(Y-Ay) - (By-Ay)*(X-Ax) )
0 on the line, and positive on one side, negative on the other side.
this is O(n^3) solution
public class Solution {
public static class Point{
long x; long y; long w;
Point(long x, long y, long w){this.x = x; this.y = y; this.w = w;}
long onLine(Point p1, Point p2){
return (p1.x - p2.x)*(this.y-p1.y)-(p1.y-p2.y)*(this.x-p1.x);
}
}
public static void main(String[] args) {
/* Enter your code here. Read input from STDIN. Print output to STDOUT. Your class should be named Solution. */
try(Scanner conin = new Scanner(System.in)){
int num = conin.nextInt();
Point[] points = new Point[num];
for(int i=0; i<num; i++){
points[i] = new Point(conin.nextLong(), conin.nextLong(), conin.nextLong());
}
long maxSum = 0;
for(int i=0; i<num; i++){
for(int j=i+1; j<num; j++){
long leftSum = 0;
long rightSum = 0;
for(int k=0; k<num; k++){
if(!(k==i || k==j)){
long left = points[k].onLine(points[i], points[j]);
if(left>0)
leftSum += points[k].w;
else
rightSum += points[k].w;
}
}
long[] sums = new long[]{leftSum, rightSum, points[i].w, points[j].w};
Arrays.sort(sums);
long sum = Math.min(sums[0]+sums[3], sums[1]+sums[2]);
maxSum = Math.max(maxSum, sum);
//sum = Math.min(sums[0], sums[1]+sums[2]+sums[3]);
//maxSum = Math.max(maxSum, sum);
sum = Math.min(sums[0]+sums[1], sums[2]+sums[3]);
maxSum = Math.max(maxSum, sum);
sum = Math.min(sums[0]+sums[1]+sums[2], sums[3]);
maxSum = Math.max(maxSum, sum);
}
}
System.out.println(maxSum);
}
}
}
Can you please elaborate the logic. Here, position = sign( (Bx-Ax)*(Y-Ay) - (By-Ay)*(X-Ax) ), Why X and Y are taken from existing points when there is a restriction of point not lying on the separating line.
ReplyDelete