on me donne 2 Intégrales, le premier est le nombre de segments (Xi, Xj) et le second est le nombre de points qui peuvent ou ne peux pas être à l'intérieur de ces segments.peut améliorer cet algorithme pour optimiser le temps de fonctionnement (trouver des points dans les segments)
A titre d'exemple, l'entrée peut être:
2 3
0 5
8 10
1 6 11
Lorsque, dans la première ligne, 2 signifie "2 segments" et 3 signifie "3 points". Les 2 segments sont "0 à 5" et "8 à 10", et les points à rechercher sont 1, 6, 11. Le signal de sortie est
1 0 0
Lorsque le point 1 se trouve dans le segment « 0 à 5 ", et les points 6 et 11 ne sont dans aucun segment. Si un point apparaît dans plus d'un segment, comme un 3, la sortie serait 2.
Le code d'origine, était juste une double boucle pour rechercher des points entre les segments. Je le Java Arrays tri rapide (modifié de façon quand il trie les points d'extrémité de segments, trie également startpoints commencent alors [i] et à la fin [i] appartiennent au même segment i) pour améliorer la vitesse de la double boucle mais il nest pas assez important.
Le code suivant fonctionne très bien, mais quand il y a trop de segments qui est très lent:
public class PointsAndSegments {
private static int[] fastCountSegments(int[] starts, int[] ends, int[] points) {
sort(starts, ends);
int[] cnt2 = CountSegments(starts,ends,points);
return cnt2;
}
private static void dualPivotQuicksort(int[] a, int[] b, int left,int right, int div) {
int len = right - left;
if (len < 27) { // insertion sort for tiny array
for (int i = left + 1; i <= right; i++) {
for (int j = i; j > left && b[j] < b[j - 1]; j--) {
swap(a, b, j, j - 1);
}
}
return;
}
int third = len/div;
// "medians"
int m1 = left + third;
int m2 = right - third;
if (m1 <= left) {
m1 = left + 1;
}
if (m2 >= right) {
m2 = right - 1;
}
if (a[m1] < a[m2]) {
swap(a, b, m1, left);
swap(a, b, m2, right);
}
else {
swap(a, b, m1, right);
swap(a, b, m2, left);
}
// pivots
int pivot1 = b[left];
int pivot2 = b[right];
// pointers
int less = left + 1;
int great = right - 1;
// sorting
for (int k = less; k <= great; k++) {
if (b[k] < pivot1) {
swap(a, b, k, less++);
}
else if (b[k] > pivot2) {
while (k < great && b[great] > pivot2) {
great--;
}
swap(a, b, k, great--);
if (b[k] < pivot1) {
swap(a, b, k, less++);
}
}
}
// swaps
int dist = great - less;
if (dist < 13) {
div++;
}
swap(a, b, less - 1, left);
swap(a, b, great + 1, right);
// subarrays
dualPivotQuicksort(a, b, left, less - 2, div);
dualPivotQuicksort(a, b, great + 2, right, div);
// equal elements
if (dist > len - 13 && pivot1 != pivot2) {
for (int k = less; k <= great; k++) {
if (b[k] == pivot1) {
swap(a, b, k, less++);
}
else if (b[k] == pivot2) {
swap(a, b, k, great--);
if (b[k] == pivot1) {
swap(a, b, k, less++);
}
}
}
}
// subarray
if (pivot1 < pivot2) {
dualPivotQuicksort(a, b, less, great, div);
}
}
public static void sort(int[] a, int[] b) {
sort(a, b, 0, b.length);
}
public static void sort(int[] a, int[] b, int fromIndex, int toIndex) {
rangeCheck(a.length, fromIndex, toIndex);
dualPivotQuicksort(a, b, fromIndex, toIndex - 1, 3);
}
private static void rangeCheck(int length, int fromIndex, int toIndex) {
if (fromIndex > toIndex) {
throw new IllegalArgumentException("fromIndex > toIndex");
}
if (fromIndex < 0) {
throw new ArrayIndexOutOfBoundsException(fromIndex);
}
if (toIndex > length) {
throw new ArrayIndexOutOfBoundsException(toIndex);
}
}
private static void swap(int[] a, int[] b, int i, int j) {
int swap1 = a[i];
int swap2 = b[i];
a[i] = a[j];
b[i] = b[j];
a[j] = swap1;
b[j] = swap2;
}
private static int[] naiveCountSegments(int[] starts, int[] ends, int[] points) {
int[] cnt = new int[points.length];
for (int i = 0; i < points.length; i++) {
for (int j = 0; j < starts.length; j++) {
if (starts[j] <= points[i] && points[i] <= ends[j]) {
cnt[i]++;
}
}
}
return cnt;
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n, m;
n = scanner.nextInt();
m = scanner.nextInt();
int[] starts = new int[n];
int[] ends = new int[n];
int[] points = new int[m];
for (int i = 0; i < n; i++) {
starts[i] = scanner.nextInt();
ends[i] = scanner.nextInt();
}
for (int i = 0; i < m; i++) {
points[i] = scanner.nextInt();
}
//use fastCountSegments
int[] cnt = fastCountSegments(starts, ends, points);
for (int x : cnt) {
System.out.print(x + " ");
}
}
Je crois que le problème est dans la méthode CountSegments() mais je ne suis pas sûr d'une autre façon de le résoudre . Supposément, je devrais utiliser un algorithme de division et de conquête, mais après 4 jours, je suis à la hauteur de n'importe quelle solution. J'ai trouvé a similar problem in CodeForces mais la sortie est différente et la plupart des solutions sont en C++. Depuis que j'ai 3 mois que j'ai commencé à apprendre Java, je pense que j'ai atteint ma limite de connaissances.
Vous devez indiquer le nombre maximum de segments et de points, pour tel ou juge en ligne comme question, il convient de prévoir? – shole
Les segments et les points sont entre 1 et 50 000 inclusivement. – Nooblhu
Le segment se chevauchera-t-il? – shole