Description
Input
Output
Sample Input
1 5 0 4 4 0 3 1 3 4 2 0 2 2 0 2 3
Sample Output
1
题意:每条线段的x轴是固定的,还有就是线段的两个端点的y坐标,要求出三个线段两两可见的一共有几对
思路:为了方便处理,要将y坐标*2来处理
#include <stdio.h> #include <string.h> #include <algorithm> using namespace std; const int L = 8000+10; int color[L<<3]; bool map[L][L];//一开始我存的int型,但是int型会超内存,用bool型能节省大量空间 int n; struct node { int l,r,n; } a[L<<3]; struct kode { int x,y1,y2; } s[L]; int cmp(kode a,kode b) { return a.x<b.x; } void init(int l,int r,int i) { a[i].l = l; a[i].r = r; a[i].n = 0; if(l==r) return; int mid = (l+r)>>1; init(l,mid,2*i); init(mid+1,r,2*i+1); } void insert(int l,int r,int i,int m) { if(l<=a[i].l && a[i].r<=r) { a[i].n = m; return ; } if(a[i].n!=-1)//将父亲节点的状态更新到孩子节点中 { a[2*i].n = a[2*i+1].n = a[i].n; a[i].n = -1; } if(l<=a[2*i].r) insert(l,r,2*i,m); if(r>=a[2*i+1].l) insert(l,r,2*i+1,m); } void query(int l,int r,int i,int m) { if(a[i].n!=-1) { map[a[i].n][m] = true; return ; } if(a[i].l == a[i].r) return; if(a[i].n!=-1) { a[2*i].n = a[2*i+1].n = a[i].n; a[i].n = -1; } if(l<=a[2*i].r) query(l,r,2*i,m); if(r>=a[2*i+1].l) query(l,r,2*i+1,m); } int main() { int t,ans,i,x,y1,y2,j,k; scanf("%d",&t); while(t--) { scanf("%d",&n); for(i = 1; i<=n; i++) { scanf("%d%d%d",&s[i].y1,&s[i].y2,&s[i].x); s[i].y1*=2; s[i].y2*=2;; } sort(s+1,s+1+n,cmp); memset(map,false,sizeof(map)); init(0,16000,1); for(i = 1; i<=n; i++) { query(s[i].y1,s[i].y2,1,i); insert(s[i].y1,s[i].y2,1,i); } ans = 0; for(i = 1; i<=n; i++)//暴力求解 for(j = 1; j<=n; j++) if(map[i][j]) { for(k = 1; k<=n; k++) if(map[i][k] && map[j][k]) ans++; } printf("%d\n",ans); } return 0; }