代码详解:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 | /**************************************************************** * Description: 2021_J_5 * Author: Alex Li * Date: 2023-09-05 18:22:52 * LastEditTime: 2023-09-15 10:15:31 ****************************************************************/ #include <stdio.h> struct point { //点的结构体,元素有x,y坐标和id int x, y, id; }; bool equals(struct point a, struct point b) { //判断两点是否相等,与id无关 return a.x == b.x && a.y == b.y; //比较a点和b点的x,y坐标,是否相等 } bool cmp(struct point a, struct point b) {//告诉sort函数排序的条件 return a.x!=b.x?a.x<b.x:a.y<b.y;//空1,如果a和b的横坐标坐标不相等,就用x坐标大小排序, } //如果a和b的横坐标相等,用纵坐标y排序 void sort(struct point A[], int n) { //冒牌排序 for (int i = 0; i < n; i++) for (int j = 1; j < n; j++) if (cmp(A[j], A[j - 1])) { //若A[j]更小,交换 struct point t = A[j]; A[j] = A[j - 1]; A[j - 1] = t; } } int unique(struct point A[], int n) {//剔除重复的点 int t = 0; for(int i = 0; i < n; i++) if (t==0||!equals(A[i],A[t-1])) //空2如果t==0,就不会执行||右侧的语句 A[t++] = A[i]; //排好序的点,重复的点一定是挨着 return t; //将不重复的点重新放入数组 } bool binary_search(struct point A[], int n, int x, int y) {//二分查找 struct point p; //查找目标 p.x = x; p.y = y; p.id = n; //id最大 int a = 0,b = n - 1; //a, b分别是二分区间左右边界 while (a < b) {//A[]升序 int mid =(a+b)>>1;//右移1位,相当于除2 if (cmp(A[mid],p))//二分,如果去右区间,说明A[mid]<p a = mid + 1; // else b = mid; } return equals(A[a], p); } #define MAXN 1000 struct point A[MAXN]; int main() { int n; scanf("%d", &n); for (int i = 0; i < n; i++) { scanf("%d %d", &A[i].x, &A[i].y); A[i].id = i; } sort(A, n);//排序 n = unique(A, n); //剔除重复 int ans = 0; for (int i = 0; i < n; i++) //枚举点对 for (int j = 0; j < n; j++) if (A[i].x<A[j].x&&A[i].y<A[j].y&& binary_search(A, n, A[i].x, A[j].y) && binary_search(A, n, A[j].x, A[i].y)) { //A[i]是左下角的点,A[j]是右上角的点 //为了四边形避免重复,所以A[i].x<A[j].x&&A[i].y&&A[i].y<A[j].y,保证A[j]一定是在A[i]的右上方。 ans++; } printf("%d", ans); return 0; } |