สามารถสรุปใจความโจทย์ได้ว่า กำหนดจุดทั้งหมด จุด โดยจุดที่ อยู่ที่พิกัด จงหา
สังเกตว่าเราสามารถแยกคิดผลบวกในแกน X และแกน Y ได้ นั่นคือ เราต้องการหา
หากเราต้องการหาผลรวมของระยะห่างระหว่างจุดทุกคู่โดยสนใจเพียงแกนเดียว การคำนวณทุกคู่จุดตรง ๆ จะต้องใช้เวลาถึง ซึ่งไม่ทันสำหรับกรณีที่ มีค่ามากถึง
เราสามารถลดระยะเวลาการทำงานได้โดยการเรียงลำดับพิกัดแต่ละแกนจากน้อยไปมาก จะเห็นว่า ระยะทางแต่ละคู่จุดสามารถแยกออกเป็นส่วน ๆ ได้
ยกตัวอย่าง หากพิกัดแกน X เป็น จะมีคู่จุดที่นำมาแบ่งส่วนระยะทางได้ดังนี้
- แยกเป็น
- แยกเป็น
- แยกเป็น
- แยกเป็น
- แยกเป็น
- แยกเป็น
ดังนั้น ผลรวมของระยะห่างแต่ละคู่ คิดได้จากการรวมระยะทาง
- ทั้งหมด ครั้ง
- ทั้งหมด ครั้ง
- ทั้งหมด ครั้ง
- ทั้งหมด ครั้ง
เข้าด้วยกัน ได้คำตอบของแกน X เป็น
กล่าวโดยทั่วไป ระยะห่างระหว่างจุดที่ กับ () จะต้องนำมาคิดทั้งหมด ครั้ง เพราะว่าระยะช่วงนั้นจะถูกคิดจากการจับคู่จุดที่อยู่ทางด้านซ้ายทั้งหมด จุดกับจุดที่อยู่ทางด้านขวา จุดเข้าด้วยกันได้ คู่
Implementation
ในภาษา C:
#include <stdio.h> #include <stdlib.h> #include <math.h> typedef long long ll; int n; int x[500000]; int y[500000]; int cmpfunc(const void *a, const void *b) { return (*(int *)a - *(int *)b); } int main(void) { scanf("%d", &n); for (int i = 0; i < n; i++) scanf("%d %d", &x[i], &y[i]); ll dist = 0; qsort(x, n, sizeof(int), &cmpfunc); qsort(y, n, sizeof(int), &cmpfunc); ll sumx = 0; ll sumy = 0; for (int i = 1; i < n; i++) { int diffx = (x[i] - x[i - 1]); sumx += diffx * i; int diffy = (y[i] - y[i - 1]); sumy += diffy * i; dist += sumx + sumy; } printf("%lld", dist); return 0; }