Cross Product + binary
If toys is on the left of the current Board, cross (L, toys, u) <0
Otherwise, it will be greater than 0 on the right.
Based on this, we perform binary classification;
Why is L instead of mid?
Let's take a look at this figure.
Add to now is L = 2, R = 5; Mid = 3; toy on the right side of 4 carboard, 5 carboard on the left side,
Execute L = L + 1 = 3, r = 5, mid = 4; still> 0 execution,
L = L + 1 = 4, r = 5, mid = 4; still greater than 0, run
L = L + 1 = 5, r = 5, exit; L = 5 at this time, toy is on the right of L, but now it is on the left. (in some cases, it will still be on the right)
Therefore, we need to add a judgment:
if(cross(CardB[r].L, Toys, CardB[r].U) < 0) N_Toys[l]++;else N_Toys[l+1]++;
Obviously, we can:
if(cross(CardB[r].L, Toys, CardB[r].U) > 0) N_Toys[r+1]++;else N_Toys[r]++;
So how can I rewrite the code by Using mid?
for(int i = 0; i < m; i++) { l = 0, r = n-1; scanf("%d%d",&Toys.x,&Toys.y); while(l <= r) { mid = (l + r) >> 1; if(cross(CardB[mid].L, Toys, CardB[mid].U) > 0) l = mid + 1; else r = mid - 1; } if(cross(CardB[mid].L, Toys, CardB[mid].U) > 0) N_Toys[mid+1]++; else N_Toys[mid]++; }
/** Poj 2318 * Fuqiang * ry preliminary * 2013/8/2 */# include <iostream> # include <cstdio> # include <cstdlib> # include <cmath> # include <cstring> # include <algorithm> using namespace STD; const int maxn = 5000 + 3; const double Pi = 4.0 * atan (1.0); const double EPS = 1e-8; struct point {int X; int y;} toys; struct line {Point U; point L;} cardb [maxn]; int n_toys [maxn]; int cross (const point & P0, const point & P1, const point & p2) // calculate the cross product {return (p1.x-margin X) * (p2.y-margin y)-(p2.x-margin X) * (p1.y-margin y);} int main () {# ifndef online_judge freopen ("in", "r", stdin); # endif int n, m, X1, Y1, X2, Y2; while (scanf ("% d", & N) {scanf ("% d", & M, & X1, & Y1, & X2, & Y2); For (INT I = 0; I <n; I ++) {scanf ("% d ", & cardb [I]. u. x, & cardb [I]. l. x); cardb [I]. u. y = Y1; cardb [I]. l. y = Y2;} memset (n_toys, 0, sizeof (n_toys); int L, R, mid, ANS, P; For (INT I = 0; I <m; I ++) {L = 0, r = n-1; scanf ("% d", & Toys. x, & Toys. y); While (L <r) {mid = (L + r)> 1; if (Cross (cardb [Mid]. l, toys, cardb [Mid]. u)> 0) L = Mid + 1; else r = mid;} If (Cross (cardb [R]. l, toys, cardb [R]. u) <0) n_toys [l] ++; else n_toys [L + 1] ++;} For (INT I = 0; I <= N; I ++) {printf ("% d: % d \ n", I, n_toys [I]);} printf ("\ n ");}}
There is also a better idea for others' code:
Use the last vertex as the cart. In this case, we only need to return l:
while (l <= r){ mid = (l + r) >> 1; if ( cal (low[mid], high[mid], cc) > 0 ) l = mid + 1; else r = mid - 1; } return l;}
Poj 2398
Add sorting and output after statistics. Note that T> 0
/** Poj 2318 * Fuqiang * ry preliminary * 2013/8/2 */# include <iostream> # include <cstdio> # include <cstdlib> # include <cmath> # include <cstring> # include <algorithm> using namespace STD; const int maxn = 5000 + 3; const double Pi = 4.0 * atan (1.0); const double EPS = 1e-8; struct point {int X; int y;} toys; struct line {Point U; point L;} cardb [maxn]; int n_toys [maxn]; int cross (const point & P0, const point & P1, const point & p2) // calculate the cross product {return (p1.x-forward X) * (p2.y-forward y)-(p2.x-forward X) * (p1.y-forward y);} int CMP (line, line B) // sort... {return. l. x <B. l. x;} int main () {# ifndef online_judge freopen ("in", "r", stdin); # endif int n, m, X1, Y1, X2, Y2; while (scanf ("% d", & N) {scanf ("% d", & M, & X1, & Y1, & X2, & Y2); For (INT I = 0; I <n; I ++) {scanf ("% d ", & cardb [I]. u. x, & cardb [I]. l. x); cardb [I]. u. y = Y1; cardb [I]. l. y = Y2;} Sort (cardb, cardb + N, CMP); // sort memset (n_toys, 0, sizeof (n_toys); int L, R, mid, ANS, p; For (INT I = 0; I <m; I ++) {L = 0, r = n-1; scanf ("% d", & Toys. x, & Toys. y); While (L <= r) {mid = (L + r)> 1; if (Cross (cardb [Mid]. l, toys, cardb [Mid]. u)> 0) L = Mid + 1; else r = mid-1;} If (Cross (cardb [Mid]. l, toys, cardb [Mid]. u)> 0) n_toys [Mid + 1] ++; else n_toys [Mid] ++;} Sort (n_toys, n_toys + n + 1 ); printf ("Box \ n"); int ST = 0; while (n_toys [st] = 0) ST ++; For (INT I = sT; I <= N;) {int num = 1; printf ("% d:", n_toys [I]); For (Int J = I ++; j <= N; j ++, I ++) {If (n_toys [I] = n_toys [J]) num ++; else break;} printf ("% d \ n ", num) ;}// printf ("\ n ");}}