一开始想线段树来统计所有直线,发现这样很难做到。
因为最多只有1e6条直线,那么直线存入结构体然后去重即可。
这里去重要对结构体重写一下== 和 <。然后就行了。
也可以把每条直线(x,y,z)换成独特的值来排序,这样可能快一点。
坑点:不在物体里的点就不要去统计了。
#include<bits/stdc++.h> using namespace std; typedef long long LL; typedef pair<int,int> pii; const int N = 1e6 + 5; const int M = 4e4+5; const LL Mod = 1e9+7; #define pi acos(-1) #define INF 1e9 #define CT0 cin.tie(0),cout.tie(0) #define IO ios::sync_with_stdio(false) #define dbg(ax) cout << "now this num is " << ax << endl; namespace FASTIO{ inline LL read(){ LL x = 0,f = 1;char c = getchar(); while(c < '0' || c > '9'){if(c == '-') f = -1;c = getchar();} while(c >= '0' && c <= '9'){x = (x<<1)+(x<<3)+(c^48);c = getchar();} return x*f; } } using namespace FASTIO; struct Node{ int x,y,z; bool operator < (const Node& a)const{ if(x == a.x){ if(y == a.y) return z < a.z; else return y < a.y; } else return x < a.x; } bool operator == (const Node& a)const{ if(x == a.x && y == a.y && z == a.z) return true; else return false; } }p[N]; int main() { int ca;ca = read(); while(ca--) { int n,m;n = read(),m = read(); int tot = 0; for(int i = 1;i <= m;++i) { char a,b; int x1,x2; scanf("%c=%d,%c=%d",&a,&x1,&b,&x2); getchar(); if(x1 < 1 || x1 > n || x2 < 1 || x2 > n) continue; if(a == 'X' && b == 'Y') for(int j = 1;j <= n;++j) p[++tot].x = x1,p[tot].y = x2,p[tot].z = j; if(a == 'Y' && b == 'X') for(int j = 1;j <= n;++j) p[++tot].x = x2,p[tot].y = x1,p[tot].z = j; if(a == 'X' && b == 'Z') for(int j = 1;j <= n;++j) p[++tot].x = x1,p[tot].y = j,p[tot].z = x2; if(a == 'Z' && b == 'X') for(int j = 1;j <= n;++j) p[++tot].x = x2,p[tot].y = j,p[tot].z = x1; if(a == 'Y' && b == 'Z') for(int j = 1;j <= n;++j) p[++tot].x = j,p[tot].y = x1,p[tot].z = x2; if(a == 'Z' && b == 'Y') for(int j = 1;j <= n;++j) p[++tot].x = j,p[tot].y = x2,p[tot].z = x1; } sort(p + 1,p + tot + 1); int len = unique(p + 1,p + tot + 1) - p - 1; printf("%d ",len); } system("pause"); return 0; }
还有一种思路就是不存具体的点然后容斥。(考虑麻烦一点)