枚举直线,对于直线的某个点在直线的左端还是右端,可以状压出一个数,用bitset记录。
然后三角形就是3个bitset&一下
#include <cstdio> #include <cstring> #include <bitset> #include <algorithm> using namespace std; typedef long long ll; const int N = 101; const int M = 1005; bitset<M> b1[N*N], b2[N*N]; int x[N], y[N], px[M], py[M]; bool check(int i, int j, int k) { if(x[i] != x[j]) { double yy = (double)(y[i] - y[j]) / (x[i] - x[j]) * (x[k] - x[i]) + y[i]; if(y[k] >= yy) return true; else return false; } else { if(x[k] >= x[i])return true; else return false; } } void put(bitset<M> x) { for(int i = 0; i < M; i ++) { if(x[i]) printf("%d ", i); }puts("*"); } int main() { int n, m, cas = 0; while(~scanf("%d%d", &n, &m)) { for(int i = 0; i < n; i ++) { scanf("%d%d", &x[i], &y[i]); } for(int i = 0; i < m; i ++) { scanf("%d%d", &px[i], &py[i]); } for(int i = 0; i < n; i ++) { for(int j = i+1; j < n; j ++) { for(int k = 0; k < m; k ++) { // printf("%d %d ", i, j); if(x[i] != x[j]) { double yy = (double)(y[i] - y[j]) / (x[i] - x[j]) * (px[k] - x[i]) + y[i]; if(py[k] == yy) { b1[i*n+j].set(k); b2[i*n+j].set(k); }else if(py[k] > yy) { b1[i*n+j].set(k); // printf("u1-%d", k); } else { b2[i*n+j].set(k); // printf("d1-%d", k); } } else { if(px[k] == x[i]) { b1[i*n+j].set(k); b2[i*n+j].set(k); } else if(px[k] > x[i]) { b1[i*n+j].set(k); // printf("u2-%d", k); } else { b2[i*n+j].set(k); // printf("d2-%d", k); } } // puts(""); } // printf(" %d %d %d %d\n", i, j, b1[i*n+j].count(), b2[i*n+j].count()); } } bitset<M> tmp(0); int ans = 0; for(int i = 0; i < n; i ++) { for(int j = i+1; j < n; j ++) { for(int k = j+1; k < n; k ++) { if(check(i, j, k)) { tmp = b1[i*n+j]; // printf("UU1 "); // put(b1[i*n+j]); } else { tmp = b2[i*n+j]; // put(b2[i*n+j]); } if(check(i, k, j)) { tmp &= b1[i*n+k]; // printf("UU2 "); // put(b1[i*n+k]); } else { tmp &= b2[i*n+k]; // put(b2[i*n+k]); } if(check(j, k, i)) { tmp &= b1[j*n+k]; // printf("UU3 "); // put(b1[j*n+k]); } else { tmp &= b2[j*n+k]; // put(b2[j*n+k]); } // printf("***%d %d %d %d\n", i, j, k, tmp.count()); if(tmp.count() & 1) ans ++; } } } printf("Case %d: %d\n", ++cas, ans); for(int i = 0; i < n*n; i ++) { b1[i].reset(); b2[i].reset(); } } return 0; } /* 3 1 0 0 0 100 100 0 0 0 3 1 0 0 0 100 100 0 50 50 3 1 0 0 0 100 100 0 100 0 3 1 0 0 0 100 100 0 0 -1 4 4 0 0 0 100 100 0 -2 50 0 0 0 100 100 0 -1 50 */